@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.
@@ -148,19 +148,174 @@ function ChatHeader({
148
148
  }
149
149
 
150
150
  // src/ui/react/components/ChatInputArea.tsx
151
- import { useState as useState2, useRef as useRef2, useImperativeHandle, forwardRef, useEffect as useEffect2, useCallback as useCallback2, useLayoutEffect } from "react";
152
- import { MicrophoneIcon, StopIcon, PaperAirplaneIcon, XMarkIcon, Square2StackIcon } from "@heroicons/react/24/outline";
151
+ import { useState as useState3, useRef as useRef3, useImperativeHandle, forwardRef, useEffect as useEffect2, useCallback as useCallback3, useLayoutEffect } from "react";
152
+ import { StopIcon, PaperAirplaneIcon, XMarkIcon as XMarkIcon2, Square2StackIcon } from "@heroicons/react/24/outline";
153
153
 
154
- // src/ui/react/hooks/useAudioRecorder.ts
154
+ // src/ui/react/components/VoiceInputButton.tsx
155
+ import { MicrophoneIcon, XMarkIcon } from "@heroicons/react/24/outline";
156
+
157
+ // src/ui/react/hooks/useDragCancel.ts
155
158
  import { useState, useRef, useCallback } from "react";
159
+ var useDragCancel = ({
160
+ onCancel,
161
+ onCommit,
162
+ isListening,
163
+ threshold = 50,
164
+ direction = "up"
165
+ }) => {
166
+ const [isDragging, setIsDragging] = useState(false);
167
+ const [isPressed, setIsPressed] = useState(false);
168
+ const startPosRef = useRef(null);
169
+ const handlePointerDown = useCallback((e) => {
170
+ startPosRef.current = { x: e.clientX, y: e.clientY };
171
+ e.currentTarget.setPointerCapture(e.pointerId);
172
+ setIsPressed(true);
173
+ setIsDragging(false);
174
+ }, []);
175
+ const handlePointerMove = useCallback((e) => {
176
+ if (!startPosRef.current || !isListening) return;
177
+ const deltaY = e.clientY - startPosRef.current.y;
178
+ const deltaX = e.clientX - startPosRef.current.x;
179
+ let shouldTrigger = false;
180
+ if (direction === "up") {
181
+ shouldTrigger = deltaY < -threshold;
182
+ } else {
183
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
184
+ shouldTrigger = distance > threshold;
185
+ }
186
+ if (shouldTrigger) {
187
+ setIsDragging(true);
188
+ } else {
189
+ setIsDragging(false);
190
+ }
191
+ }, [isListening, threshold, direction]);
192
+ const handlePointerUp = useCallback((e) => {
193
+ if (!startPosRef.current) return;
194
+ const deltaY = e.clientY - startPosRef.current.y;
195
+ const deltaX = e.clientX - startPosRef.current.x;
196
+ let isCancelled = false;
197
+ if (direction === "up") {
198
+ isCancelled = deltaY < -threshold;
199
+ } else {
200
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
201
+ isCancelled = distance > threshold;
202
+ }
203
+ if (isListening && isCancelled) {
204
+ onCancel();
205
+ } else {
206
+ onCommit();
207
+ }
208
+ startPosRef.current = null;
209
+ setIsDragging(false);
210
+ setIsPressed(false);
211
+ e.currentTarget.releasePointerCapture(e.pointerId);
212
+ }, [isListening, threshold, direction, onCancel, onCommit]);
213
+ const handlePointerCancel = useCallback((e) => {
214
+ startPosRef.current = null;
215
+ setIsDragging(false);
216
+ setIsPressed(false);
217
+ }, []);
218
+ return {
219
+ handlers: {
220
+ onPointerDown: handlePointerDown,
221
+ onPointerMove: handlePointerMove,
222
+ onPointerUp: handlePointerUp,
223
+ onPointerCancel: handlePointerCancel
224
+ },
225
+ isDragging,
226
+ isPressed
227
+ };
228
+ };
229
+
230
+ // src/ui/react/components/VoiceInputButton.tsx
231
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
232
+ var VoiceInputButton = ({
233
+ voiceConfig,
234
+ voiceTrigger,
235
+ isTranscribing,
236
+ setVoiceTrigger,
237
+ setShowDebug,
238
+ tapCountRef,
239
+ customRecorder,
240
+ startRecording,
241
+ stopRecording
242
+ }) => {
243
+ const { handlers, isDragging, isPressed } = useDragCancel({
244
+ isListening: !!voiceTrigger,
245
+ onCancel: () => {
246
+ var _a;
247
+ console.log("[ChatInputArea] Gesture Cancel");
248
+ customRecorder.cancel();
249
+ setVoiceTrigger(null);
250
+ (_a = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a.call(voiceConfig);
251
+ },
252
+ onCommit: () => {
253
+ const now = Date.now();
254
+ if (now - tapCountRef.current.lastTap < 500) {
255
+ tapCountRef.current.count++;
256
+ } else {
257
+ tapCountRef.current.count = 1;
258
+ }
259
+ tapCountRef.current.lastTap = now;
260
+ if (tapCountRef.current.count >= 5) {
261
+ setShowDebug((prev) => !prev);
262
+ tapCountRef.current.count = 0;
263
+ stopRecording();
264
+ return;
265
+ }
266
+ if (voiceTrigger) {
267
+ stopRecording();
268
+ } else if (!isTranscribing) {
269
+ startRecording("click");
270
+ }
271
+ },
272
+ threshold: 30
273
+ });
274
+ let btnClass = "text-gray-500 border-gray-300 bg-white hover:text-gray-700 hover:bg-gray-100";
275
+ let icon = /* @__PURE__ */ jsx5(MicrophoneIcon, { className: "w-5 h-5" });
276
+ if (isTranscribing) {
277
+ btnClass = "text-white border-indigo-500 bg-indigo-600 scale-110 shadow-lg cursor-wait";
278
+ icon = /* @__PURE__ */ jsx5("div", { className: "animate-spin w-5 h-5 flex items-center justify-center", children: /* @__PURE__ */ jsxs3("svg", { className: "w-5 h-5 text-white", viewBox: "0 0 24 24", children: [
279
+ /* @__PURE__ */ jsx5("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", fill: "none" }),
280
+ /* @__PURE__ */ jsx5("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" })
281
+ ] }) });
282
+ } else if (voiceTrigger) {
283
+ btnClass = "text-white border-orange-400 bg-orange-500 scale-110 shadow-lg animate-pulse";
284
+ }
285
+ return /* @__PURE__ */ jsxs3("div", { className: "relative flex flex-col items-center", children: [
286
+ voiceTrigger && !isTranscribing && isPressed && /* @__PURE__ */ jsxs3("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
287
+ ${isDragging ? "bg-red-500 text-white scale-110" : "bg-white text-red-500 border border-red-100"}`, children: [
288
+ /* @__PURE__ */ jsx5("div", { className: `transition-transform duration-300 ${isDragging ? "rotate-180" : ""}`, children: isDragging ? /* @__PURE__ */ jsx5(XMarkIcon, { className: "w-4 h-4" }) : "\u2191" }),
289
+ /* @__PURE__ */ jsx5("span", { children: isDragging ? "Release to Cancel" : "Drag here to cancel" }),
290
+ /* @__PURE__ */ jsx5("div", { className: `absolute top-full left-4 -translate-x-1/2 border-8 border-transparent transition-colors duration-200
291
+ ${isDragging ? "border-t-red-500" : "border-t-white"}` })
292
+ ] }),
293
+ /* @__PURE__ */ jsx5(
294
+ "button",
295
+ {
296
+ type: "button",
297
+ ...handlers,
298
+ className: `mb-1 p-2 rounded-full transition-all duration-300 flex-shrink-0 border touch-none select-none ${btnClass}`,
299
+ disabled: isTranscribing,
300
+ title: isTranscribing ? "Transcribing..." : isDragging ? "Release to Cancel" : voiceTrigger ? "Stop Recording" : "Start Voice Input",
301
+ children: icon
302
+ }
303
+ )
304
+ ] });
305
+ };
306
+
307
+ // src/ui/react/hooks/useAudioRecorder.ts
308
+ import { useState as useState2, useRef as useRef2, useCallback as useCallback2 } from "react";
156
309
  var useAudioRecorder = (onStop) => {
157
- const [isRecording, setIsRecording] = useState(false);
158
- const [isSimulated, setIsSimulated] = useState(false);
159
- const [blob, setBlob] = useState(null);
160
- const [error, setError] = useState(null);
161
- const mediaRecorderRef = useRef(null);
162
- const chunksRef = useRef([]);
163
- const start = useCallback(async () => {
310
+ const [isRecording, setIsRecording] = useState2(false);
311
+ const [isSimulated, setIsSimulated] = useState2(false);
312
+ const [blob, setBlob] = useState2(null);
313
+ const [error, setError] = useState2(null);
314
+ const mediaRecorderRef = useRef2(null);
315
+ const chunksRef = useRef2([]);
316
+ const cancelledRef = useRef2(false);
317
+ const start = useCallback2(async () => {
318
+ cancelledRef.current = false;
164
319
  try {
165
320
  if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
166
321
  if (process.env.NODE_ENV === "development") {
@@ -187,6 +342,14 @@ var useAudioRecorder = (onStop) => {
187
342
  }
188
343
  };
189
344
  mediaRecorder.onstop = () => {
345
+ if (cancelledRef.current) {
346
+ console.log("[useAudioRecorder] Recording cancelled, discarding data.");
347
+ setIsRecording(false);
348
+ stream.getTracks().forEach((track) => {
349
+ track.stop();
350
+ });
351
+ return;
352
+ }
190
353
  const audioBlob = new Blob(chunksRef.current, { type: "audio/webm" });
191
354
  setBlob(audioBlob);
192
355
  setIsRecording(false);
@@ -203,7 +366,7 @@ var useAudioRecorder = (onStop) => {
203
366
  setError(e.message || "Microphone access denied");
204
367
  }
205
368
  }, [onStop]);
206
- const stop = useCallback(() => {
369
+ const stop = useCallback2(() => {
207
370
  if (isSimulated) {
208
371
  setIsRecording(false);
209
372
  setIsSimulated(false);
@@ -216,11 +379,23 @@ var useAudioRecorder = (onStop) => {
216
379
  mediaRecorderRef.current.stop();
217
380
  }
218
381
  }, [isSimulated, onStop]);
382
+ const cancel = useCallback2(() => {
383
+ cancelledRef.current = true;
384
+ if (isSimulated) {
385
+ setIsRecording(false);
386
+ setIsSimulated(false);
387
+ return;
388
+ }
389
+ if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
390
+ mediaRecorderRef.current.stop();
391
+ }
392
+ }, [isSimulated]);
219
393
  return {
220
394
  isRecording,
221
395
  isSimulated,
222
396
  start,
223
397
  stop,
398
+ cancel,
224
399
  blob,
225
400
  error
226
401
  };
@@ -248,7 +423,7 @@ function useProactiveResize(textareaRef, measurementRef, value, disabled) {
248
423
  }
249
424
 
250
425
  // src/ui/react/components/ChatInputArea.tsx
251
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
426
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
252
427
  var ChatInputArea = forwardRef(({
253
428
  onSubmit,
254
429
  isSending,
@@ -265,14 +440,14 @@ var ChatInputArea = forwardRef(({
265
440
  defaultInputMode = "text"
266
441
  }, ref) => {
267
442
  var _a, _b, _c, _d;
268
- const [internalMessage, setInternalMessage] = useState2("");
269
- const [voiceTrigger, setVoiceTrigger] = useState2(null);
270
- const [isTranscribing, setIsTranscribing] = useState2(false);
271
- const [voiceError, setVoiceError] = useState2(null);
272
- const [isFocused, setIsFocused] = useState2(false);
273
- const [showDebug, setShowDebug] = useState2(false);
274
- const [logs, setLogs] = useState2([]);
275
- const tapCountRef = useRef2({ count: 0, lastTap: 0 });
443
+ const [internalMessage, setInternalMessage] = useState3("");
444
+ const [voiceTrigger, setVoiceTrigger] = useState3(null);
445
+ const [isTranscribing, setIsTranscribing] = useState3(false);
446
+ const [voiceError, setVoiceError] = useState3(null);
447
+ const [isFocused, setIsFocused] = useState3(false);
448
+ const [showDebug, setShowDebug] = useState3(false);
449
+ const [logs, setLogs] = useState3([]);
450
+ const tapCountRef = useRef3({ count: 0, lastTap: 0 });
276
451
  useEffect2(() => {
277
452
  const originalLog = console.log;
278
453
  const originalWarn = console.warn;
@@ -306,15 +481,15 @@ var ChatInputArea = forwardRef(({
306
481
  console.error = originalError;
307
482
  };
308
483
  }, []);
309
- const copyLogs = useCallback2(() => {
484
+ const copyLogs = useCallback3(() => {
310
485
  navigator.clipboard.writeText(logs.join("\n")).then(() => alert("Logs copied to clipboard")).catch((err) => console.error("Failed to copy logs", err));
311
486
  }, [logs]);
312
- const textareaRef = useRef2(null);
313
- const measurementRef = useRef2(null);
314
- const pendingSelectionRef = useRef2(null);
487
+ const textareaRef = useRef3(null);
488
+ const measurementRef = useRef3(null);
489
+ const pendingSelectionRef = useRef3(null);
315
490
  const isControlled = value !== void 0;
316
491
  const message = isControlled ? value : internalMessage;
317
- const messageRef = useRef2(message);
492
+ const messageRef = useRef3(message);
318
493
  messageRef.current = message;
319
494
  useLayoutEffect(() => {
320
495
  if (pendingSelectionRef.current && textareaRef.current) {
@@ -324,18 +499,18 @@ var ChatInputArea = forwardRef(({
324
499
  pendingSelectionRef.current = null;
325
500
  }
326
501
  }, [message]);
327
- const onChangeRef = useRef2(onChange);
502
+ const onChangeRef = useRef3(onChange);
328
503
  useEffect2(() => {
329
504
  onChangeRef.current = onChange;
330
505
  }, [onChange]);
331
506
  const { voice: globalVoice } = useChatConfig();
332
507
  const isVoiceEnabled = (_a = globalVoice == null ? void 0 : globalVoice.enabled) != null ? _a : !!propVoiceConfig;
333
508
  const voiceConfig = isVoiceEnabled ? propVoiceConfig || (globalVoice == null ? void 0 : globalVoice.config) : void 0;
334
- const voiceConfigRef = useRef2(voiceConfig);
509
+ const voiceConfigRef = useRef3(voiceConfig);
335
510
  useEffect2(() => {
336
511
  voiceConfigRef.current = voiceConfig;
337
512
  }, [voiceConfig]);
338
- const triggerChange = useCallback2((newValue) => {
513
+ const triggerChange = useCallback3((newValue) => {
339
514
  setVoiceError(null);
340
515
  if (isControlled && onChangeRef.current) {
341
516
  const syntheticEvent = {
@@ -349,7 +524,7 @@ var ChatInputArea = forwardRef(({
349
524
  }, [isControlled]);
350
525
  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));
351
526
  useProactiveResize(textareaRef, measurementRef, message, isInputDisabled || !!voiceTrigger);
352
- const insertTextAtCursor = useCallback2((text) => {
527
+ const insertTextAtCursor = useCallback3((text) => {
353
528
  const textarea = textareaRef.current;
354
529
  const currentVal = messageRef.current || "";
355
530
  if (!textarea) {
@@ -367,12 +542,12 @@ var ChatInputArea = forwardRef(({
367
542
  pendingSelectionRef.current = { start: selectionStart, end: selectionEnd };
368
543
  triggerChange(newText);
369
544
  }, [triggerChange]);
370
- const handleVoiceResult = useCallback2((text, isFinal) => {
545
+ const handleVoiceResult = useCallback3((text, isFinal) => {
371
546
  if (isFinal) {
372
547
  insertTextAtCursor(text);
373
548
  }
374
549
  }, [insertTextAtCursor]);
375
- const handleVoiceEnd = useCallback2(() => {
550
+ const handleVoiceEnd = useCallback3(() => {
376
551
  var _a2, _b2;
377
552
  setVoiceTrigger(null);
378
553
  (_b2 = (_a2 = voiceConfigRef.current) == null ? void 0 : _a2.onVoiceEnd) == null ? void 0 : _b2.call(_a2);
@@ -483,62 +658,43 @@ var ChatInputArea = forwardRef(({
483
658
  if (!showInputForm) {
484
659
  return null;
485
660
  }
486
- return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col w-full relative", children: [
487
- showDebug && /* @__PURE__ */ jsxs3("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: [
488
- /* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
489
- /* @__PURE__ */ jsx5("span", { children: "Debug Logs" }),
490
- /* @__PURE__ */ jsxs3("div", { className: "flex gap-2", children: [
491
- /* @__PURE__ */ jsx5("button", { onClick: copyLogs, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ jsx5(Square2StackIcon, { className: "w-4 h-4" }) }),
492
- /* @__PURE__ */ jsx5("button", { onClick: () => {
661
+ return /* @__PURE__ */ jsxs4("div", { className: "flex flex-col w-full relative", children: [
662
+ showDebug && /* @__PURE__ */ jsxs4("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: [
663
+ /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
664
+ /* @__PURE__ */ jsx6("span", { children: "Debug Logs" }),
665
+ /* @__PURE__ */ jsxs4("div", { className: "flex gap-2", children: [
666
+ /* @__PURE__ */ jsx6("button", { onClick: copyLogs, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ jsx6(Square2StackIcon, { className: "w-4 h-4" }) }),
667
+ /* @__PURE__ */ jsx6("button", { onClick: () => {
493
668
  copyLogs();
494
669
  setShowDebug(false);
495
- }, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ jsx5(XMarkIcon, { className: "w-4 h-4" }) })
670
+ }, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ jsx6(XMarkIcon2, { className: "w-4 h-4" }) })
496
671
  ] })
497
672
  ] }),
498
- logs.map((log, i) => /* @__PURE__ */ jsx5("div", { className: "mb-0.5 border-b border-gray-700/50 pb-0.5 break-all", children: log }, i)),
499
- logs.length === 0 && /* @__PURE__ */ jsx5("div", { children: "No logs yet..." })
673
+ logs.map((log, i) => /* @__PURE__ */ jsx6("div", { className: "mb-0.5 border-b border-gray-700/50 pb-0.5 break-all", children: log }, i)),
674
+ logs.length === 0 && /* @__PURE__ */ jsx6("div", { children: "No logs yet..." })
500
675
  ] }),
501
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
502
- voiceConfig && /* @__PURE__ */ jsx5(
503
- "button",
676
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
677
+ voiceConfig && /* @__PURE__ */ jsx6(
678
+ VoiceInputButton,
504
679
  {
505
- type: "button",
506
- onClick: () => {
507
- const now = Date.now();
508
- if (now - tapCountRef.current.lastTap < 500) {
509
- tapCountRef.current.count++;
510
- } else {
511
- tapCountRef.current.count = 1;
512
- }
513
- tapCountRef.current.lastTap = now;
514
- if (tapCountRef.current.count >= 5) {
515
- setShowDebug((prev) => !prev);
516
- tapCountRef.current.count = 0;
517
- stopRecording();
518
- return;
519
- }
520
- if (voiceTrigger) {
521
- stopRecording();
522
- } else if (!isTranscribing) {
523
- startRecording("click");
524
- }
525
- },
526
- 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" : ""}`,
527
- disabled: isTranscribing,
528
- title: isTranscribing ? "Transcribing..." : voiceTrigger ? "Stop Recording" : "Start Voice Input",
529
- children: isTranscribing ? /* @__PURE__ */ jsx5("div", { className: "animate-spin w-5 h-5 flex items-center justify-center", children: /* @__PURE__ */ jsxs3("svg", { className: "w-5 h-5 text-white", viewBox: "0 0 24 24", children: [
530
- /* @__PURE__ */ jsx5("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", fill: "none" }),
531
- /* @__PURE__ */ jsx5("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" })
532
- ] }) }) : /* @__PURE__ */ jsx5(MicrophoneIcon, { className: "w-5 h-5" })
680
+ voiceConfig,
681
+ voiceTrigger,
682
+ isTranscribing,
683
+ setVoiceTrigger,
684
+ setShowDebug,
685
+ tapCountRef,
686
+ customRecorder,
687
+ startRecording,
688
+ stopRecording
533
689
  }
534
690
  ),
535
- /* @__PURE__ */ jsxs3(
691
+ /* @__PURE__ */ jsxs4(
536
692
  "div",
537
693
  {
538
694
  tabIndex: -1,
539
695
  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"}`,
540
696
  children: [
541
- /* @__PURE__ */ jsx5(
697
+ /* @__PURE__ */ jsx6(
542
698
  "span",
543
699
  {
544
700
  ref: measurementRef,
@@ -546,7 +702,7 @@ var ChatInputArea = forwardRef(({
546
702
  style: { fontSize: "1rem" }
547
703
  }
548
704
  ),
549
- /* @__PURE__ */ jsx5(
705
+ /* @__PURE__ */ jsx6(
550
706
  "textarea",
551
707
  {
552
708
  ref: textareaRef,
@@ -571,8 +727,8 @@ var ChatInputArea = forwardRef(({
571
727
  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" : ""}`
572
728
  }
573
729
  ),
574
- /* @__PURE__ */ jsxs3("div", { className: "relative mx-2 flex-shrink-0", children: [
575
- isSending && /* @__PURE__ */ jsx5("div", { className: "absolute -inset-1", children: /* @__PURE__ */ jsxs3(
730
+ /* @__PURE__ */ jsxs4("div", { className: "relative mx-2 flex-shrink-0", children: [
731
+ isSending && /* @__PURE__ */ jsx6("div", { className: "absolute -inset-1", children: /* @__PURE__ */ jsxs4(
576
732
  "svg",
577
733
  {
578
734
  className: "animate-spin h-full w-full text-blue-500 opacity-75",
@@ -580,7 +736,7 @@ var ChatInputArea = forwardRef(({
580
736
  fill: "none",
581
737
  viewBox: "0 0 24 24",
582
738
  children: [
583
- /* @__PURE__ */ jsx5(
739
+ /* @__PURE__ */ jsx6(
584
740
  "circle",
585
741
  {
586
742
  className: "opacity-25",
@@ -591,7 +747,7 @@ var ChatInputArea = forwardRef(({
591
747
  strokeWidth: "4"
592
748
  }
593
749
  ),
594
- /* @__PURE__ */ jsx5(
750
+ /* @__PURE__ */ jsx6(
595
751
  "path",
596
752
  {
597
753
  className: "opacity-75",
@@ -602,7 +758,7 @@ var ChatInputArea = forwardRef(({
602
758
  ]
603
759
  }
604
760
  ) }),
605
- /* @__PURE__ */ jsx5(
761
+ /* @__PURE__ */ jsx6(
606
762
  "button",
607
763
  {
608
764
  type: "button",
@@ -617,7 +773,7 @@ var ChatInputArea = forwardRef(({
617
773
  disabled: (currentTask == null ? void 0 : currentTask.complete) || isSending && !onStop || isInputDisabled,
618
774
  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"}`,
619
775
  title: isSending && onStop ? "Stop generating" : "Send message",
620
- children: isSending ? onStop ? /* @__PURE__ */ jsx5(StopIcon, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx5("div", { className: "w-5 h-5" }) : /* @__PURE__ */ jsx5(PaperAirplaneIcon, { className: "h-5 w-5" })
776
+ children: isSending ? onStop ? /* @__PURE__ */ jsx6(StopIcon, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx6("div", { className: "w-5 h-5" }) : /* @__PURE__ */ jsx6(PaperAirplaneIcon, { className: "h-5 w-5" })
621
777
  }
622
778
  )
623
779
  ] })
@@ -625,19 +781,19 @@ var ChatInputArea = forwardRef(({
625
781
  }
626
782
  )
627
783
  ] }),
628
- inputHint && /* @__PURE__ */ jsx5("div", { className: "text-sm text-red-500 bg-red-50 py-1 px-4 rounded-lg mt-1", children: inputHint }),
629
- /* @__PURE__ */ jsx5("div", { className: "ml-[46px] mb-2 mt-0.5 min-h-[0.75rem]", style: { marginLeft: "48px" }, children: /* @__PURE__ */ jsx5("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__ */ jsxs3("span", { className: "flex items-center gap-1 font-semibold italic", children: [
784
+ inputHint && /* @__PURE__ */ jsx6("div", { className: "text-sm text-red-500 bg-red-50 py-1 px-4 rounded-lg mt-1", children: inputHint }),
785
+ /* @__PURE__ */ jsx6("div", { className: "ml-[46px] mb-2 mt-0.5 min-h-[0.75rem]", style: { marginLeft: "48px" }, children: /* @__PURE__ */ jsx6("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__ */ jsxs4("span", { className: "flex items-center gap-1 font-semibold italic", children: [
630
786
  "Error: ",
631
787
  voiceError
632
- ] }) : 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...") }) })
788
+ ] }) : isTranscribing ? "Transcribing... please wait" : voiceTrigger ? "Listening... Tap again to stop" : hintText || (voiceConfig ? "Type in text or tap mic icon to talk" : "Type your message...") }) })
633
789
  ] });
634
790
  });
635
791
  ChatInputArea.displayName = "ChatInputArea";
636
792
 
637
793
  // src/ui/react/components/TapToTalk.tsx
638
- import React3, { useState as useState3, useCallback as useCallback3, useRef as useRef3 } from "react";
639
- import { MicrophoneIcon as MicrophoneIcon2, XMarkIcon as XMarkIcon2, Square2StackIcon as Square2StackIcon2 } from "@heroicons/react/24/outline";
640
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
794
+ import React3, { useState as useState4, useCallback as useCallback4, useRef as useRef4 } from "react";
795
+ import { MicrophoneIcon as MicrophoneIcon3, XMarkIcon as XMarkIcon3, Square2StackIcon as Square2StackIcon2 } from "@heroicons/react/24/outline";
796
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
641
797
  var TapToTalk = ({
642
798
  onResult,
643
799
  voiceConfig: propVoiceConfig,
@@ -650,12 +806,12 @@ var TapToTalk = ({
650
806
  var _a;
651
807
  const globalConfig = useChatConfig();
652
808
  const voiceConfig = propVoiceConfig || ((_a = globalConfig.voice) == null ? void 0 : _a.config);
653
- const [isTranscribing, setIsTranscribing] = useState3(false);
654
- const [voiceTrigger, setVoiceTrigger] = useState3(null);
655
- const [errorMsg, setErrorMsg] = useState3(null);
656
- const [showDebug, setShowDebug] = useState3(false);
657
- const [logs, setLogs] = useState3([]);
658
- const tapCountRef = useRef3({ count: 0, lastTap: 0 });
809
+ const [isTranscribing, setIsTranscribing] = useState4(false);
810
+ const [voiceTrigger, setVoiceTrigger] = useState4(null);
811
+ const [errorMsg, setErrorMsg] = useState4(null);
812
+ const [showDebug, setShowDebug] = useState4(false);
813
+ const [logs, setLogs] = useState4([]);
814
+ const tapCountRef = useRef4({ count: 0, lastTap: 0 });
659
815
  React3.useEffect(() => {
660
816
  const originalLog = console.log;
661
817
  const originalWarn = console.warn;
@@ -689,13 +845,14 @@ var TapToTalk = ({
689
845
  console.error = originalError;
690
846
  };
691
847
  }, []);
692
- const copyLogs = useCallback3(() => {
848
+ const copyLogs = useCallback4(() => {
693
849
  navigator.clipboard.writeText(logs.join("\n")).then(() => alert("Logs copied to clipboard")).catch((err) => console.error("Failed to copy logs", err));
694
850
  }, [logs]);
695
- const handleVoiceEnd = useCallback3(() => {
851
+ const handleVoiceEnd = useCallback4(() => {
696
852
  setVoiceTrigger(null);
697
853
  }, []);
698
854
  const customRecorder = useAudioRecorder(async (blob) => {
855
+ var _a2;
699
856
  setVoiceTrigger(null);
700
857
  setIsTranscribing(true);
701
858
  setErrorMsg(null);
@@ -719,11 +876,13 @@ var TapToTalk = ({
719
876
  } else {
720
877
  setIsTranscribing(false);
721
878
  }
879
+ (_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a2.call(voiceConfig);
722
880
  });
723
881
  const isListening = !!voiceTrigger || customRecorder.isRecording;
724
882
  const isActive = isListening || isTranscribing;
725
- const processingRef = useRef3(false);
883
+ const processingRef = useRef4(false);
726
884
  const toggleVoice = async () => {
885
+ var _a2, _b, _c;
727
886
  if (processingRef.current) {
728
887
  console.log("[TapToTalk] toggleVoice ignored - processing");
729
888
  return;
@@ -756,17 +915,20 @@ var TapToTalk = ({
756
915
  console.log("[TapToTalk] Stopping voice...");
757
916
  customRecorder.stop();
758
917
  setVoiceTrigger(null);
918
+ (_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a2.call(voiceConfig);
759
919
  } else {
760
920
  console.log("[TapToTalk] Starting voice...");
761
921
  setErrorMsg(null);
762
922
  onFocusTarget == null ? void 0 : onFocusTarget();
763
923
  setVoiceTrigger("click");
924
+ (_b = voiceConfig == null ? void 0 : voiceConfig.onVoiceStart) == null ? void 0 : _b.call(voiceConfig);
764
925
  try {
765
926
  await customRecorder.start();
766
927
  } catch (e) {
767
928
  console.error("[TapToTalk] Custom recorder failed:", e);
768
929
  setErrorMsg("Mic access denied");
769
930
  setVoiceTrigger(null);
931
+ (_c = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _c.call(voiceConfig);
770
932
  }
771
933
  }
772
934
  } finally {
@@ -775,54 +937,75 @@ var TapToTalk = ({
775
937
  }, 300);
776
938
  }
777
939
  };
940
+ const { handlers, isDragging, isPressed } = useDragCancel({
941
+ isListening: !!voiceTrigger,
942
+ onCancel: () => {
943
+ var _a2;
944
+ console.log("[TapToTalk] Gesture Cancel");
945
+ customRecorder.cancel();
946
+ setVoiceTrigger(null);
947
+ (_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a2.call(voiceConfig);
948
+ },
949
+ onCommit: () => {
950
+ toggleVoice();
951
+ },
952
+ threshold: 30
953
+ });
778
954
  let bgColor = accentColor;
779
955
  let label = "Tap to Talk";
780
- let Icon = /* @__PURE__ */ jsx6(MicrophoneIcon2, { className: "h-5 w-5" });
956
+ let Icon = /* @__PURE__ */ jsx7(MicrophoneIcon3, { className: "h-5 w-5" });
781
957
  if (isListening) {
782
958
  bgColor = "bg-orange-500";
783
- label = "Listening ... Tap to stop";
784
- Icon = /* @__PURE__ */ jsx6(MicrophoneIcon2, { className: "h-5 w-5 animate-pulse" });
959
+ label = "Listening... Tap again to stop";
960
+ Icon = /* @__PURE__ */ jsx7(MicrophoneIcon3, { className: "h-5 w-5 animate-pulse" });
785
961
  } else if (isTranscribing) {
786
962
  bgColor = "bg-indigo-600";
787
963
  label = "Transcribing ...";
788
- Icon = /* @__PURE__ */ jsxs4("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: [
789
- /* @__PURE__ */ jsx6("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
790
- /* @__PURE__ */ jsx6("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" })
964
+ Icon = /* @__PURE__ */ jsxs5("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: [
965
+ /* @__PURE__ */ jsx7("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
966
+ /* @__PURE__ */ jsx7("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" })
791
967
  ] });
792
968
  }
793
- return /* @__PURE__ */ jsxs4("div", { className: "flex flex-col w-full relative", children: [
794
- showDebug && /* @__PURE__ */ jsxs4("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: [
795
- /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
796
- /* @__PURE__ */ jsx6("span", { children: "Debug Logs" }),
797
- /* @__PURE__ */ jsxs4("div", { className: "flex gap-2", children: [
798
- /* @__PURE__ */ jsx6("button", { onClick: (e) => {
969
+ return /* @__PURE__ */ jsxs5("div", { className: "flex flex-col w-full relative items-center", children: [
970
+ isListening && !isTranscribing && isPressed && /* @__PURE__ */ jsxs5("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
971
+ ${isDragging ? "bg-red-500 text-white scale-110" : "bg-white text-red-500 border border-red-100"}`, children: [
972
+ /* @__PURE__ */ jsx7("div", { className: `transition-transform duration-300 ${isDragging ? "rotate-180" : ""}`, children: isDragging ? /* @__PURE__ */ jsx7(XMarkIcon3, { className: "w-5 h-5" }) : "\u2191" }),
973
+ /* @__PURE__ */ jsx7("span", { children: isDragging ? "Release to Cancel" : "Drag here to cancel" }),
974
+ /* @__PURE__ */ jsx7("div", { className: `absolute top-full left-1/2 -translate-x-1/2 border-8 border-transparent transition-colors duration-200
975
+ ${isDragging ? "border-t-red-500" : "border-t-white"}` })
976
+ ] }),
977
+ showDebug && /* @__PURE__ */ jsxs5("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: [
978
+ /* @__PURE__ */ jsxs5("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
979
+ /* @__PURE__ */ jsx7("span", { children: "Debug Logs" }),
980
+ /* @__PURE__ */ jsxs5("div", { className: "flex gap-2", children: [
981
+ /* @__PURE__ */ jsx7("button", { onClick: (e) => {
799
982
  e.stopPropagation();
800
983
  copyLogs();
801
- }, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ jsx6(Square2StackIcon2, { className: "w-4 h-4" }) }),
802
- /* @__PURE__ */ jsx6("button", { onClick: (e) => {
984
+ }, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ jsx7(Square2StackIcon2, { className: "w-4 h-4" }) }),
985
+ /* @__PURE__ */ jsx7("button", { onClick: (e) => {
803
986
  e.stopPropagation();
804
987
  copyLogs();
805
988
  setShowDebug(false);
806
- }, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ jsx6(XMarkIcon2, { className: "w-4 h-4" }) })
989
+ }, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ jsx7(XMarkIcon3, { className: "w-4 h-4" }) })
807
990
  ] })
808
991
  ] }),
809
- logs.map((log, i) => /* @__PURE__ */ jsx6("div", { className: "mb-0.5 border-b border-gray-700/50 pb-0.5 break-all", children: log }, i)),
810
- logs.length === 0 && /* @__PURE__ */ jsx6("div", { children: "No logs yet..." })
992
+ logs.map((log, i) => /* @__PURE__ */ jsx7("div", { className: "mb-0.5 border-b border-gray-700/50 pb-0.5 break-all", children: log }, i)),
993
+ logs.length === 0 && /* @__PURE__ */ jsx7("div", { children: "No logs yet..." })
811
994
  ] }),
812
- /* @__PURE__ */ jsxs4(
995
+ /* @__PURE__ */ jsxs5(
813
996
  "button",
814
997
  {
815
- onClick: toggleVoice,
998
+ ...handlers,
816
999
  disabled: disabled || isTranscribing && !isListening,
817
- 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]
1000
+ 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
818
1001
  ${bgColor} text-white
819
1002
  ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
820
1003
  ${className}`,
821
1004
  title: label,
822
1005
  children: [
823
- /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center shrink-0", children: Icon }),
824
- /* @__PURE__ */ jsx6("span", { className: "truncate", children: label }),
825
- errorMsg && /* @__PURE__ */ jsx6("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 })
1006
+ /* @__PURE__ */ jsx7("div", { className: "flex items-center justify-center shrink-0", children: Icon }),
1007
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: label }),
1008
+ errorMsg && /* @__PURE__ */ jsx7("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 })
826
1009
  ]
827
1010
  }
828
1011
  )
@@ -830,17 +1013,17 @@ var TapToTalk = ({
830
1013
  };
831
1014
 
832
1015
  // src/ui/react/components/ChatMessageList.tsx
833
- import { useEffect as useEffect5, useRef as useRef5 } from "react";
1016
+ import { useEffect as useEffect5, useRef as useRef6 } from "react";
834
1017
 
835
1018
  // src/ui/react/components/interactive/ConfirmInteraction.tsx
836
- import { useState as useState4 } from "react";
837
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1019
+ import { useState as useState5 } from "react";
1020
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
838
1021
  var ConfirmInteraction = ({
839
1022
  parameters,
840
1023
  onResponse,
841
1024
  isResponseSubmitted
842
1025
  }) => {
843
- const [selectedOption, setSelectedOption] = useState4(null);
1026
+ const [selectedOption, setSelectedOption] = useState5(null);
844
1027
  const params = parameters;
845
1028
  const { yesPrompt, noPrompt } = params;
846
1029
  console.log("[ConfirmInteraction] Parameters:", params);
@@ -849,8 +1032,8 @@ var ConfirmInteraction = ({
849
1032
  setSelectedOption(buttonText);
850
1033
  onResponse(value);
851
1034
  };
852
- return /* @__PURE__ */ jsx7("div", { className: "mt-2 mb-4", children: /* @__PURE__ */ jsxs5("div", { className: "flex space-x-2", children: [
853
- /* @__PURE__ */ jsx7(
1035
+ return /* @__PURE__ */ jsx8("div", { className: "mt-2 mb-4", children: /* @__PURE__ */ jsxs6("div", { className: "flex space-x-2", children: [
1036
+ /* @__PURE__ */ jsx8(
854
1037
  "button",
855
1038
  {
856
1039
  onClick: () => handleOptionClick(true, yesPrompt),
@@ -859,7 +1042,7 @@ var ConfirmInteraction = ({
859
1042
  children: yesPrompt
860
1043
  }
861
1044
  ),
862
- /* @__PURE__ */ jsx7(
1045
+ /* @__PURE__ */ jsx8(
863
1046
  "button",
864
1047
  {
865
1048
  onClick: () => handleOptionClick(false, noPrompt),
@@ -873,16 +1056,16 @@ var ConfirmInteraction = ({
873
1056
  var ConfirmInteraction_default = ConfirmInteraction;
874
1057
 
875
1058
  // src/ui/react/components/interactive/SelectInteraction.tsx
876
- import { useState as useState5, useEffect as useEffect3 } from "react";
877
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1059
+ import { useState as useState6, useEffect as useEffect3 } from "react";
1060
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
878
1061
  var SelectInteraction = ({
879
1062
  parameters,
880
1063
  onResponse,
881
1064
  isResponseSubmitted,
882
1065
  message
883
1066
  }) => {
884
- const [selectedOption, setSelectedOption] = useState5(null);
885
- const [customOption, setCustomOption] = useState5(null);
1067
+ const [selectedOption, setSelectedOption] = useState6(null);
1068
+ const [customOption, setCustomOption] = useState6(null);
886
1069
  const params = parameters;
887
1070
  const { question, options, placeholder } = params;
888
1071
  useEffect3(() => {
@@ -900,8 +1083,8 @@ var SelectInteraction = ({
900
1083
  setCustomOption(null);
901
1084
  onResponse(option);
902
1085
  };
903
- return /* @__PURE__ */ jsxs6("div", { className: "mt-2 mb-4", children: [
904
- /* @__PURE__ */ jsx8("div", { className: "flex flex-wrap gap-2", children: options.map((option, index) => /* @__PURE__ */ jsx8(
1086
+ return /* @__PURE__ */ jsxs7("div", { className: "mt-2 mb-4", children: [
1087
+ /* @__PURE__ */ jsx9("div", { className: "flex flex-wrap gap-2", children: options.map((option, index) => /* @__PURE__ */ jsx9(
905
1088
  "button",
906
1089
  {
907
1090
  onClick: () => handleOptionClick(option),
@@ -911,9 +1094,9 @@ var SelectInteraction = ({
911
1094
  },
912
1095
  index
913
1096
  )) }),
914
- customOption && isResponseSubmitted && /* @__PURE__ */ jsxs6("div", { className: "mt-2 text-sm text-amber-600 bg-amber-50 p-2 rounded", children: [
1097
+ customOption && isResponseSubmitted && /* @__PURE__ */ jsxs7("div", { className: "mt-2 text-sm text-amber-600 bg-amber-50 p-2 rounded", children: [
915
1098
  "User provided custom option: ",
916
- /* @__PURE__ */ jsxs6("span", { className: "font-semibold", children: [
1099
+ /* @__PURE__ */ jsxs7("span", { className: "font-semibold", children: [
917
1100
  '"',
918
1101
  customOption,
919
1102
  '"'
@@ -924,20 +1107,20 @@ var SelectInteraction = ({
924
1107
  var SelectInteraction_default = SelectInteraction;
925
1108
 
926
1109
  // src/ui/react/components/interactive/FormInteraction.tsx
927
- import { useState as useState6, useEffect as useEffect4, useRef as useRef4 } from "react";
1110
+ import { useState as useState7, useEffect as useEffect4, useRef as useRef5 } from "react";
928
1111
  import { ChevronDownIcon, ChevronUpIcon } from "lucide-react";
929
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1112
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
930
1113
  var FormInteraction = ({
931
1114
  parameters,
932
1115
  onResponse,
933
1116
  isResponseSubmitted,
934
1117
  submittedValues
935
1118
  }) => {
936
- const [isModalOpen, setIsModalOpen] = useState6(false);
937
- const [formValues, setFormValues] = useState6({});
938
- const [isExpanded, setIsExpanded] = useState6(false);
939
- const [parsedFields, setParsedFields] = useState6([]);
940
- const formButtonsRef = useRef4(null);
1119
+ const [isModalOpen, setIsModalOpen] = useState7(false);
1120
+ const [formValues, setFormValues] = useState7({});
1121
+ const [isExpanded, setIsExpanded] = useState7(false);
1122
+ const [parsedFields, setParsedFields] = useState7([]);
1123
+ const formButtonsRef = useRef5(null);
941
1124
  const parseParameters = () => {
942
1125
  const { prompt, description, submitText = "Submit", cancelText = "Cancel" } = parameters;
943
1126
  let fieldsArray = [];
@@ -1046,12 +1229,12 @@ var FormInteraction = ({
1046
1229
  case "email":
1047
1230
  case "number":
1048
1231
  case "password":
1049
- return /* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-center space-x-4", children: [
1050
- /* @__PURE__ */ jsxs7("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px]", children: [
1232
+ return /* @__PURE__ */ jsxs8("div", { className: "mb-4 flex items-center space-x-4", children: [
1233
+ /* @__PURE__ */ jsxs8("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px]", children: [
1051
1234
  label,
1052
- required && /* @__PURE__ */ jsx9("span", { className: "text-red-500", children: "*" })
1235
+ required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
1053
1236
  ] }),
1054
- /* @__PURE__ */ jsx9(
1237
+ /* @__PURE__ */ jsx10(
1055
1238
  "input",
1056
1239
  {
1057
1240
  type: type === "string" ? "text" : type,
@@ -1067,12 +1250,12 @@ var FormInteraction = ({
1067
1250
  )
1068
1251
  ] }, name);
1069
1252
  case "textarea":
1070
- return /* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-start space-x-4", children: [
1071
- /* @__PURE__ */ jsxs7("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px] pt-2", children: [
1253
+ return /* @__PURE__ */ jsxs8("div", { className: "mb-4 flex items-start space-x-4", children: [
1254
+ /* @__PURE__ */ jsxs8("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px] pt-2", children: [
1072
1255
  label,
1073
- required && /* @__PURE__ */ jsx9("span", { className: "text-red-500", children: "*" })
1256
+ required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
1074
1257
  ] }),
1075
- /* @__PURE__ */ jsx9(
1258
+ /* @__PURE__ */ jsx10(
1076
1259
  "textarea",
1077
1260
  {
1078
1261
  id: name,
@@ -1088,12 +1271,12 @@ var FormInteraction = ({
1088
1271
  )
1089
1272
  ] }, name);
1090
1273
  case "select":
1091
- return /* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-center space-x-4", children: [
1092
- /* @__PURE__ */ jsxs7("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px]", children: [
1274
+ return /* @__PURE__ */ jsxs8("div", { className: "mb-4 flex items-center space-x-4", children: [
1275
+ /* @__PURE__ */ jsxs8("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px]", children: [
1093
1276
  label,
1094
- required && /* @__PURE__ */ jsx9("span", { className: "text-red-500", children: "*" })
1277
+ required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
1095
1278
  ] }),
1096
- /* @__PURE__ */ jsxs7(
1279
+ /* @__PURE__ */ jsxs8(
1097
1280
  "select",
1098
1281
  {
1099
1282
  id: name,
@@ -1104,17 +1287,17 @@ var FormInteraction = ({
1104
1287
  disabled: isResponseSubmitted,
1105
1288
  className: "flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1106
1289
  children: [
1107
- /* @__PURE__ */ jsx9("option", { value: "", disabled: true, children: placeholder || "Select an option" }),
1108
- options == null ? void 0 : options.map((option, index) => /* @__PURE__ */ jsx9("option", { value: option, children: option }, index))
1290
+ /* @__PURE__ */ jsx10("option", { value: "", disabled: true, children: placeholder || "Select an option" }),
1291
+ options == null ? void 0 : options.map((option, index) => /* @__PURE__ */ jsx10("option", { value: option, children: option }, index))
1109
1292
  ]
1110
1293
  }
1111
1294
  )
1112
1295
  ] }, name);
1113
1296
  case "checkbox":
1114
- return /* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-center space-x-4", children: [
1115
- /* @__PURE__ */ jsx9("div", { className: "min-w-[120px]" }),
1116
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center", children: [
1117
- /* @__PURE__ */ jsx9(
1297
+ return /* @__PURE__ */ jsxs8("div", { className: "mb-4 flex items-center space-x-4", children: [
1298
+ /* @__PURE__ */ jsx10("div", { className: "min-w-[120px]" }),
1299
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center", children: [
1300
+ /* @__PURE__ */ jsx10(
1118
1301
  "input",
1119
1302
  {
1120
1303
  type: "checkbox",
@@ -1127,20 +1310,20 @@ var FormInteraction = ({
1127
1310
  className: "h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
1128
1311
  }
1129
1312
  ),
1130
- /* @__PURE__ */ jsxs7("label", { htmlFor: name, className: "ml-2 text-sm text-gray-700", children: [
1313
+ /* @__PURE__ */ jsxs8("label", { htmlFor: name, className: "ml-2 text-sm text-gray-700", children: [
1131
1314
  label,
1132
- required && /* @__PURE__ */ jsx9("span", { className: "text-red-500", children: "*" })
1315
+ required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
1133
1316
  ] })
1134
1317
  ] })
1135
1318
  ] }, name);
1136
1319
  case "radio":
1137
- return /* @__PURE__ */ jsxs7("div", { className: "mb-4 flex space-x-4", children: [
1138
- /* @__PURE__ */ jsxs7("div", { className: "text-sm font-medium text-gray-700 min-w-[120px] pt-2", children: [
1320
+ return /* @__PURE__ */ jsxs8("div", { className: "mb-4 flex space-x-4", children: [
1321
+ /* @__PURE__ */ jsxs8("div", { className: "text-sm font-medium text-gray-700 min-w-[120px] pt-2", children: [
1139
1322
  label,
1140
- required && /* @__PURE__ */ jsx9("span", { className: "text-red-500", children: "*" })
1323
+ required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
1141
1324
  ] }),
1142
- /* @__PURE__ */ jsx9("div", { className: "flex-1 space-y-2", children: options == null ? void 0 : options.map((option, index) => /* @__PURE__ */ jsxs7("div", { className: "flex items-center", children: [
1143
- /* @__PURE__ */ jsx9(
1325
+ /* @__PURE__ */ jsx10("div", { className: "flex-1 space-y-2", children: options == null ? void 0 : options.map((option, index) => /* @__PURE__ */ jsxs8("div", { className: "flex items-center", children: [
1326
+ /* @__PURE__ */ jsx10(
1144
1327
  "input",
1145
1328
  {
1146
1329
  id: `${name}-${index}`,
@@ -1154,7 +1337,7 @@ var FormInteraction = ({
1154
1337
  className: "h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500"
1155
1338
  }
1156
1339
  ),
1157
- /* @__PURE__ */ jsx9("label", { htmlFor: `${name}-${index}`, className: "ml-2 text-sm text-gray-700", children: option })
1340
+ /* @__PURE__ */ jsx10("label", { htmlFor: `${name}-${index}`, className: "ml-2 text-sm text-gray-700", children: option })
1158
1341
  ] }, index)) })
1159
1342
  ] }, name);
1160
1343
  default:
@@ -1162,27 +1345,27 @@ var FormInteraction = ({
1162
1345
  }
1163
1346
  };
1164
1347
  if (isResponseSubmitted) {
1165
- return /* @__PURE__ */ jsxs7("div", { className: "mt-2 bg-gray-50 p-3 rounded-md border border-gray-200", children: [
1166
- /* @__PURE__ */ jsxs7("div", { className: "flex justify-between items-center cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
1167
- /* @__PURE__ */ jsxs7("span", { className: "font-medium text-gray-700", children: [
1348
+ return /* @__PURE__ */ jsxs8("div", { className: "mt-2 bg-gray-50 p-3 rounded-md border border-gray-200", children: [
1349
+ /* @__PURE__ */ jsxs8("div", { className: "flex justify-between items-center cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
1350
+ /* @__PURE__ */ jsxs8("span", { className: "font-medium text-gray-700", children: [
1168
1351
  isExpanded ? "Hide" : "Show",
1169
1352
  " Form Responses"
1170
1353
  ] }),
1171
- isExpanded ? /* @__PURE__ */ jsx9(ChevronUpIcon, { className: "h-5 w-5 text-gray-500" }) : /* @__PURE__ */ jsx9(ChevronDownIcon, { className: "h-5 w-5 text-gray-500" })
1354
+ isExpanded ? /* @__PURE__ */ jsx10(ChevronUpIcon, { className: "h-5 w-5 text-gray-500" }) : /* @__PURE__ */ jsx10(ChevronDownIcon, { className: "h-5 w-5 text-gray-500" })
1172
1355
  ] }),
1173
- isExpanded && /* @__PURE__ */ jsx9("div", { className: "mt-2 space-y-2", children: parsedFields.map((field) => /* @__PURE__ */ jsxs7("div", { className: "flex", children: [
1174
- /* @__PURE__ */ jsxs7("span", { className: "text-sm font-medium text-gray-600 mr-2", children: [
1356
+ isExpanded && /* @__PURE__ */ jsx10("div", { className: "mt-2 space-y-2", children: parsedFields.map((field) => /* @__PURE__ */ jsxs8("div", { className: "flex", children: [
1357
+ /* @__PURE__ */ jsxs8("span", { className: "text-sm font-medium text-gray-600 mr-2", children: [
1175
1358
  field.label,
1176
1359
  ":"
1177
1360
  ] }),
1178
- /* @__PURE__ */ jsx9("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" })
1361
+ /* @__PURE__ */ jsx10("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" })
1179
1362
  ] }, field.name)) })
1180
1363
  ] });
1181
1364
  }
1182
- return /* @__PURE__ */ jsx9("div", { className: "mt-2", children: isModalOpen && /* @__PURE__ */ jsx9("div", { className: "p-4", children: /* @__PURE__ */ jsxs7("form", { onSubmit: handleSubmit, className: "mt-4", children: [
1365
+ return /* @__PURE__ */ jsx10("div", { className: "mt-2", children: isModalOpen && /* @__PURE__ */ jsx10("div", { className: "p-4", children: /* @__PURE__ */ jsxs8("form", { onSubmit: handleSubmit, className: "mt-4", children: [
1183
1366
  parsedFields.map((field) => renderField(field)),
1184
- /* @__PURE__ */ jsxs7("div", { ref: formButtonsRef, className: "flex justify-end mt-4 space-x-2", children: [
1185
- /* @__PURE__ */ jsx9(
1367
+ /* @__PURE__ */ jsxs8("div", { ref: formButtonsRef, className: "flex justify-end mt-4 space-x-2", children: [
1368
+ /* @__PURE__ */ jsx10(
1186
1369
  "button",
1187
1370
  {
1188
1371
  type: "button",
@@ -1192,7 +1375,7 @@ var FormInteraction = ({
1192
1375
  children: params.cancelText
1193
1376
  }
1194
1377
  ),
1195
- /* @__PURE__ */ jsx9(
1378
+ /* @__PURE__ */ jsx10(
1196
1379
  "button",
1197
1380
  {
1198
1381
  type: "submit",
@@ -1207,12 +1390,12 @@ var FormInteraction = ({
1207
1390
  var FormInteraction_default = FormInteraction;
1208
1391
 
1209
1392
  // src/ui/react/components/interactive/PresentInteraction.tsx
1210
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
1393
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
1211
1394
  var ReactMarkdown2;
1212
1395
  try {
1213
1396
  ReactMarkdown2 = __require("react-markdown");
1214
1397
  } catch (error) {
1215
- ReactMarkdown2 = ({ children }) => /* @__PURE__ */ jsx10("div", { className: "whitespace-pre-wrap", children });
1398
+ ReactMarkdown2 = ({ children }) => /* @__PURE__ */ jsx11("div", { className: "whitespace-pre-wrap", children });
1216
1399
  }
1217
1400
  var PresentInteraction = ({
1218
1401
  parameters
@@ -1250,15 +1433,15 @@ var PresentInteraction = ({
1250
1433
  }
1251
1434
  };
1252
1435
  const styles = getLevelStyles();
1253
- return /* @__PURE__ */ jsxs8("div", { className: `mt-2 mb-4 p-4 ${styles.container} border rounded-md`, children: [
1254
- title && /* @__PURE__ */ jsx10("div", { className: `font-medium ${styles.title} mb-2`, children: title }),
1255
- /* @__PURE__ */ jsx10("div", { className: `text-sm ${styles.content}`, children: format === "markdown" ? /* @__PURE__ */ jsx10(ReactMarkdown2, { className: "prose prose-sm max-w-none", children: content }) : format === "html" ? /* @__PURE__ */ jsx10("div", { dangerouslySetInnerHTML: { __html: content } }) : /* @__PURE__ */ jsx10("div", { className: "whitespace-pre-wrap", children: content }) })
1436
+ return /* @__PURE__ */ jsxs9("div", { className: `mt-2 mb-4 p-4 ${styles.container} border rounded-md`, children: [
1437
+ title && /* @__PURE__ */ jsx11("div", { className: `font-medium ${styles.title} mb-2`, children: title }),
1438
+ /* @__PURE__ */ jsx11("div", { className: `text-sm ${styles.content}`, children: format === "markdown" ? /* @__PURE__ */ jsx11(ReactMarkdown2, { className: "prose prose-sm max-w-none", children: content }) : format === "html" ? /* @__PURE__ */ jsx11("div", { dangerouslySetInnerHTML: { __html: content } }) : /* @__PURE__ */ jsx11("div", { className: "whitespace-pre-wrap", children: content }) })
1256
1439
  ] });
1257
1440
  };
1258
1441
  var PresentInteraction_default = PresentInteraction;
1259
1442
 
1260
1443
  // src/ui/react/components/interactive/InteractiveMessageHandler.tsx
1261
- import { jsx as jsx11 } from "react/jsx-runtime";
1444
+ import { jsx as jsx12 } from "react/jsx-runtime";
1262
1445
  var InteractiveMessageHandler = ({
1263
1446
  message,
1264
1447
  onResponse,
@@ -1269,7 +1452,7 @@ var InteractiveMessageHandler = ({
1269
1452
  const submittedResponse = parentMessage == null ? void 0 : parentMessage.responseValue;
1270
1453
  switch (functionType) {
1271
1454
  case "confirm":
1272
- return /* @__PURE__ */ jsx11(
1455
+ return /* @__PURE__ */ jsx12(
1273
1456
  ConfirmInteraction_default,
1274
1457
  {
1275
1458
  parameters,
@@ -1278,7 +1461,7 @@ var InteractiveMessageHandler = ({
1278
1461
  }
1279
1462
  );
1280
1463
  case "select":
1281
- return /* @__PURE__ */ jsx11(
1464
+ return /* @__PURE__ */ jsx12(
1282
1465
  SelectInteraction_default,
1283
1466
  {
1284
1467
  parameters,
@@ -1288,7 +1471,7 @@ var InteractiveMessageHandler = ({
1288
1471
  }
1289
1472
  );
1290
1473
  case "form":
1291
- return /* @__PURE__ */ jsx11(
1474
+ return /* @__PURE__ */ jsx12(
1292
1475
  FormInteraction_default,
1293
1476
  {
1294
1477
  parameters,
@@ -1298,7 +1481,7 @@ var InteractiveMessageHandler = ({
1298
1481
  }
1299
1482
  );
1300
1483
  case "present":
1301
- return /* @__PURE__ */ jsx11(
1484
+ return /* @__PURE__ */ jsx12(
1302
1485
  PresentInteraction_default,
1303
1486
  {
1304
1487
  parameters
@@ -1315,7 +1498,7 @@ var InteractiveMessageHandler_default = InteractiveMessageHandler;
1315
1498
 
1316
1499
  // src/ui/react/components/ChatMessageList.tsx
1317
1500
  import { InformationCircleIcon } from "@heroicons/react/24/outline";
1318
- import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
1501
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1319
1502
  var ChatMessageList = ({
1320
1503
  chatHistory,
1321
1504
  isProcessing,
@@ -1324,9 +1507,9 @@ var ChatMessageList = ({
1324
1507
  getContextExample,
1325
1508
  onInteractiveResponse
1326
1509
  }) => {
1327
- const chatContainerRef = useRef5(null);
1328
- const lastMessageRef = useRef5(null);
1329
- const processingIndicatorRef = useRef5(null);
1510
+ const chatContainerRef = useRef6(null);
1511
+ const lastMessageRef = useRef6(null);
1512
+ const processingIndicatorRef = useRef6(null);
1330
1513
  useEffect5(() => {
1331
1514
  if (isProcessing && processingIndicatorRef.current) {
1332
1515
  processingIndicatorRef.current.scrollIntoView({ behavior: "smooth" });
@@ -1343,15 +1526,15 @@ var ChatMessageList = ({
1343
1526
  onInteractiveResponse(messageId, response);
1344
1527
  }
1345
1528
  };
1346
- return /* @__PURE__ */ jsxs9(
1529
+ return /* @__PURE__ */ jsxs10(
1347
1530
  "div",
1348
1531
  {
1349
1532
  ref: chatContainerRef,
1350
1533
  className: "flex-1 overflow-y-auto p-4 space-y-8 bg-gray-50",
1351
1534
  children: [
1352
- chatHistory.length === 0 && !isProcessing && /* @__PURE__ */ jsxs9("div", { className: "text-center py-8", children: [
1353
- /* @__PURE__ */ jsx12("h3", { className: "text-lg font-medium text-gray-700 mb-2", children: "How can I help you today?" }),
1354
- /* @__PURE__ */ jsxs9("p", { className: "text-sm text-gray-500 mb-4", children: [
1535
+ chatHistory.length === 0 && !isProcessing && /* @__PURE__ */ jsxs10("div", { className: "text-center py-8", children: [
1536
+ /* @__PURE__ */ jsx13("h3", { className: "text-lg font-medium text-gray-700 mb-2", children: "How can I help you today?" }),
1537
+ /* @__PURE__ */ jsxs10("p", { className: "text-sm text-gray-500 mb-4", children: [
1355
1538
  "Try asking me something like ",
1356
1539
  getContextExample()
1357
1540
  ] })
@@ -1360,14 +1543,14 @@ var ChatMessageList = ({
1360
1543
  const isLastMessage = index === chatHistory.length - 1;
1361
1544
  const isUser = message.role === "user";
1362
1545
  const isError = message.role === "error";
1363
- return /* @__PURE__ */ jsxs9(
1546
+ return /* @__PURE__ */ jsxs10(
1364
1547
  "div",
1365
1548
  {
1366
1549
  ref: isLastMessage ? lastMessageRef : void 0,
1367
1550
  className: `flex flex-col w-full ${isUser ? "items-end" : "items-start"}`,
1368
1551
  children: [
1369
- /* @__PURE__ */ jsx12("div", { className: "text-xs text-gray-400 mb-1 px-1", children: message.timestamp ? `${isUser ? "Sent" : "Received"} at ${new Date(message.timestamp).toLocaleString()}` : "" }),
1370
- /* @__PURE__ */ jsx12("div", { className: "w-full", children: message.interactive && message.interactiveData ? /* @__PURE__ */ jsx12("div", { className: `max-w-[85%] ${isUser ? "ml-auto" : "mr-auto"}`, children: /* @__PURE__ */ jsx12(
1552
+ /* @__PURE__ */ jsx13("div", { className: "text-xs text-gray-400 mb-1 px-1", children: message.timestamp ? `${isUser ? "Sent" : "Received"} at ${new Date(message.timestamp).toLocaleString()}` : "" }),
1553
+ /* @__PURE__ */ jsx13("div", { className: "w-full", children: message.interactive && message.interactiveData ? /* @__PURE__ */ jsx13("div", { className: `max-w-[85%] ${isUser ? "ml-auto" : "mr-auto"}`, children: /* @__PURE__ */ jsx13(
1371
1554
  InteractiveMessageHandler_default,
1372
1555
  {
1373
1556
  message: message.interactiveData,
@@ -1379,16 +1562,16 @@ var ChatMessageList = ({
1379
1562
  isResponseSubmitted: !!message.isResponseSubmitted,
1380
1563
  parentMessage: message
1381
1564
  }
1382
- ) }) : /* @__PURE__ */ jsx12(
1565
+ ) }) : /* @__PURE__ */ jsx13(
1383
1566
  MessageBubble,
1384
1567
  {
1385
1568
  message,
1386
1569
  isUser
1387
1570
  }
1388
1571
  ) }),
1389
- isUser && message.interactive && /* @__PURE__ */ jsxs9("div", { className: "flex items-center mt-1 space-x-1 text-xs text-gray-500 italic", children: [
1390
- /* @__PURE__ */ jsx12(InformationCircleIcon, { className: "h-3 w-3 text-blue-400" }),
1391
- /* @__PURE__ */ jsxs9("span", { children: [
1572
+ isUser && message.interactive && /* @__PURE__ */ jsxs10("div", { className: "flex items-center mt-1 space-x-1 text-xs text-gray-500 italic", children: [
1573
+ /* @__PURE__ */ jsx13(InformationCircleIcon, { className: "h-3 w-3 text-blue-400" }),
1574
+ /* @__PURE__ */ jsxs10("span", { children: [
1392
1575
  message.request === "form" && "Response to form submission",
1393
1576
  message.request === "select" && "Response to selection prompt",
1394
1577
  message.request === "confirm" && "Response to confirmation prompt"
@@ -1399,29 +1582,29 @@ var ChatMessageList = ({
1399
1582
  message.id || `message-${index}`
1400
1583
  );
1401
1584
  }),
1402
- isProcessing && /* @__PURE__ */ jsx12(
1585
+ isProcessing && /* @__PURE__ */ jsx13(
1403
1586
  "div",
1404
1587
  {
1405
1588
  ref: processingIndicatorRef,
1406
1589
  className: "flex justify-start my-4",
1407
- children: /* @__PURE__ */ jsx12("div", { className: "bg-white text-gray-800 border border-gray-200 rounded-lg px-4 py-2 max-w-[85%]", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center", children: [
1408
- /* @__PURE__ */ jsx12("span", { className: "text-sm", children: processingHint }),
1409
- /* @__PURE__ */ jsxs9("span", { className: "ml-2 flex space-x-1", children: [
1410
- /* @__PURE__ */ jsx12("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0ms" } }),
1411
- /* @__PURE__ */ jsx12("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "150ms" } }),
1412
- /* @__PURE__ */ jsx12("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "300ms" } })
1590
+ children: /* @__PURE__ */ jsx13("div", { className: "bg-white text-gray-800 border border-gray-200 rounded-lg px-4 py-2 max-w-[85%]", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center", children: [
1591
+ /* @__PURE__ */ jsx13("span", { className: "text-sm", children: processingHint }),
1592
+ /* @__PURE__ */ jsxs10("span", { className: "ml-2 flex space-x-1", children: [
1593
+ /* @__PURE__ */ jsx13("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0ms" } }),
1594
+ /* @__PURE__ */ jsx13("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "150ms" } }),
1595
+ /* @__PURE__ */ jsx13("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "300ms" } })
1413
1596
  ] })
1414
1597
  ] }) })
1415
1598
  }
1416
1599
  ),
1417
- currentTask && !currentTask.complete && /* @__PURE__ */ jsxs9("div", { className: "mt-4 bg-blue-50 border border-blue-100 rounded-lg p-3", children: [
1418
- /* @__PURE__ */ jsxs9("div", { className: "text-sm text-blue-800 mb-1", children: [
1600
+ currentTask && !currentTask.complete && /* @__PURE__ */ jsxs10("div", { className: "mt-4 bg-blue-50 border border-blue-100 rounded-lg p-3", children: [
1601
+ /* @__PURE__ */ jsxs10("div", { className: "text-sm text-blue-800 mb-1", children: [
1419
1602
  "Task in progress: Step ",
1420
1603
  currentTask.currentStep,
1421
1604
  " of ",
1422
1605
  currentTask.steps
1423
1606
  ] }),
1424
- /* @__PURE__ */ jsx12("div", { className: "w-full bg-blue-200 rounded-full h-2", children: /* @__PURE__ */ jsx12(
1607
+ /* @__PURE__ */ jsx13("div", { className: "w-full bg-blue-200 rounded-full h-2", children: /* @__PURE__ */ jsx13(
1425
1608
  "div",
1426
1609
  {
1427
1610
  className: "bg-blue-500 h-2 rounded-full",
@@ -1436,34 +1619,34 @@ var ChatMessageList = ({
1436
1619
 
1437
1620
  // src/ui/react/components/ConnectionStatus.tsx
1438
1621
  import { Wifi, WifiOff, RefreshCw } from "lucide-react";
1439
- import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1622
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1440
1623
  var ConnectionStatus = ({
1441
1624
  connectionStatus,
1442
1625
  onReconnect
1443
1626
  }) => {
1444
- return /* @__PURE__ */ jsxs10("div", { className: "bg-amber-100 connection-status flex items-center justify-between px-4 py-1 text-xs", children: [
1445
- /* @__PURE__ */ jsx13("div", { className: "text-gray-700 font-medium", children: "You are talking with your personal Content Strategist" }),
1446
- connectionStatus === "connected" && /* @__PURE__ */ jsxs10("div", { className: "flex items-center text-green-600", children: [
1447
- /* @__PURE__ */ jsx13(Wifi, { className: "w-3 h-3 mr-1" }),
1448
- /* @__PURE__ */ jsx13("span", { children: "Connected" })
1627
+ return /* @__PURE__ */ jsxs11("div", { className: "bg-amber-100 connection-status flex items-center justify-between px-4 py-1 text-xs", children: [
1628
+ /* @__PURE__ */ jsx14("div", { className: "text-gray-700 font-medium", children: "You are talking with your personal Content Strategist" }),
1629
+ connectionStatus === "connected" && /* @__PURE__ */ jsxs11("div", { className: "flex items-center text-green-600", children: [
1630
+ /* @__PURE__ */ jsx14(Wifi, { className: "w-3 h-3 mr-1" }),
1631
+ /* @__PURE__ */ jsx14("span", { children: "Connected" })
1449
1632
  ] }),
1450
- connectionStatus === "reconnecting" && /* @__PURE__ */ jsxs10("div", { className: "flex items-center text-amber-600", children: [
1451
- /* @__PURE__ */ jsx13(RefreshCw, { className: "w-3 h-3 mr-1 animate-spin" }),
1452
- /* @__PURE__ */ jsx13("span", { children: "Reconnecting..." })
1633
+ connectionStatus === "reconnecting" && /* @__PURE__ */ jsxs11("div", { className: "flex items-center text-amber-600", children: [
1634
+ /* @__PURE__ */ jsx14(RefreshCw, { className: "w-3 h-3 mr-1 animate-spin" }),
1635
+ /* @__PURE__ */ jsx14("span", { children: "Reconnecting..." })
1453
1636
  ] }),
1454
- connectionStatus === "disconnected" && /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
1455
- /* @__PURE__ */ jsxs10("div", { className: "text-red-600 flex items-center", children: [
1456
- /* @__PURE__ */ jsx13(WifiOff, { className: "w-3 h-3 mr-1" }),
1457
- /* @__PURE__ */ jsx13("span", { children: "Disconnected" })
1637
+ connectionStatus === "disconnected" && /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
1638
+ /* @__PURE__ */ jsxs11("div", { className: "text-red-600 flex items-center", children: [
1639
+ /* @__PURE__ */ jsx14(WifiOff, { className: "w-3 h-3 mr-1" }),
1640
+ /* @__PURE__ */ jsx14("span", { children: "Disconnected" })
1458
1641
  ] }),
1459
- /* @__PURE__ */ jsxs10(
1642
+ /* @__PURE__ */ jsxs11(
1460
1643
  "button",
1461
1644
  {
1462
1645
  onClick: onReconnect,
1463
1646
  className: "text-blue-600 hover:text-blue-800 flex items-center",
1464
1647
  children: [
1465
- /* @__PURE__ */ jsx13(RefreshCw, { className: "w-3 h-3 mr-1" }),
1466
- /* @__PURE__ */ jsx13("span", { children: "Reconnect" })
1648
+ /* @__PURE__ */ jsx14(RefreshCw, { className: "w-3 h-3 mr-1" }),
1649
+ /* @__PURE__ */ jsx14("span", { children: "Reconnect" })
1467
1650
  ]
1468
1651
  }
1469
1652
  )
@@ -1472,7 +1655,7 @@ var ConnectionStatus = ({
1472
1655
  };
1473
1656
 
1474
1657
  // src/ui/react/components/Spinner.tsx
1475
- import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1658
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1476
1659
  var Spinner = ({
1477
1660
  size = "md",
1478
1661
  className = "",
@@ -1484,7 +1667,7 @@ var Spinner = ({
1484
1667
  lg: "h-8 w-8",
1485
1668
  xl: "h-12 w-12"
1486
1669
  };
1487
- return /* @__PURE__ */ jsxs11(
1670
+ return /* @__PURE__ */ jsxs12(
1488
1671
  "svg",
1489
1672
  {
1490
1673
  className: `animate-spin ${sizeClasses[size]} ${color} ${className}`,
@@ -1492,7 +1675,7 @@ var Spinner = ({
1492
1675
  fill: "none",
1493
1676
  viewBox: "0 0 24 24",
1494
1677
  children: [
1495
- /* @__PURE__ */ jsx14(
1678
+ /* @__PURE__ */ jsx15(
1496
1679
  "circle",
1497
1680
  {
1498
1681
  className: "opacity-25",
@@ -1503,7 +1686,7 @@ var Spinner = ({
1503
1686
  strokeWidth: "4"
1504
1687
  }
1505
1688
  ),
1506
- /* @__PURE__ */ jsx14(
1689
+ /* @__PURE__ */ jsx15(
1507
1690
  "path",
1508
1691
  {
1509
1692
  className: "opacity-75",