@contentgrowth/llm-service 1.0.1 → 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,10 +845,10 @@ 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) => {
@@ -724,7 +880,7 @@ var TapToTalk = ({
724
880
  });
725
881
  const isListening = !!voiceTrigger || customRecorder.isRecording;
726
882
  const isActive = isListening || isTranscribing;
727
- const processingRef = useRef3(false);
883
+ const processingRef = useRef4(false);
728
884
  const toggleVoice = async () => {
729
885
  var _a2, _b, _c;
730
886
  if (processingRef.current) {
@@ -781,54 +937,75 @@ var TapToTalk = ({
781
937
  }, 300);
782
938
  }
783
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
+ });
784
954
  let bgColor = accentColor;
785
955
  let label = "Tap to Talk";
786
- let Icon = /* @__PURE__ */ jsx6(MicrophoneIcon2, { className: "h-5 w-5" });
956
+ let Icon = /* @__PURE__ */ jsx7(MicrophoneIcon3, { className: "h-5 w-5" });
787
957
  if (isListening) {
788
958
  bgColor = "bg-orange-500";
789
- label = "Listening ... Tap to stop";
790
- 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" });
791
961
  } else if (isTranscribing) {
792
962
  bgColor = "bg-indigo-600";
793
963
  label = "Transcribing ...";
794
- 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: [
795
- /* @__PURE__ */ jsx6("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
796
- /* @__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" })
797
967
  ] });
798
968
  }
799
- return /* @__PURE__ */ jsxs4("div", { className: "flex flex-col w-full relative", children: [
800
- 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: [
801
- /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
802
- /* @__PURE__ */ jsx6("span", { children: "Debug Logs" }),
803
- /* @__PURE__ */ jsxs4("div", { className: "flex gap-2", children: [
804
- /* @__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) => {
805
982
  e.stopPropagation();
806
983
  copyLogs();
807
- }, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ jsx6(Square2StackIcon2, { className: "w-4 h-4" }) }),
808
- /* @__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) => {
809
986
  e.stopPropagation();
810
987
  copyLogs();
811
988
  setShowDebug(false);
812
- }, 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" }) })
813
990
  ] })
814
991
  ] }),
815
- 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)),
816
- 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..." })
817
994
  ] }),
818
- /* @__PURE__ */ jsxs4(
995
+ /* @__PURE__ */ jsxs5(
819
996
  "button",
820
997
  {
821
- onClick: toggleVoice,
998
+ ...handlers,
822
999
  disabled: disabled || isTranscribing && !isListening,
823
- 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
824
1001
  ${bgColor} text-white
825
1002
  ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
826
1003
  ${className}`,
827
1004
  title: label,
828
1005
  children: [
829
- /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center shrink-0", children: Icon }),
830
- /* @__PURE__ */ jsx6("span", { className: "truncate", children: label }),
831
- 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 })
832
1009
  ]
833
1010
  }
834
1011
  )
@@ -836,17 +1013,17 @@ var TapToTalk = ({
836
1013
  };
837
1014
 
838
1015
  // src/ui/react/components/ChatMessageList.tsx
839
- import { useEffect as useEffect5, useRef as useRef5 } from "react";
1016
+ import { useEffect as useEffect5, useRef as useRef6 } from "react";
840
1017
 
841
1018
  // src/ui/react/components/interactive/ConfirmInteraction.tsx
842
- import { useState as useState4 } from "react";
843
- 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";
844
1021
  var ConfirmInteraction = ({
845
1022
  parameters,
846
1023
  onResponse,
847
1024
  isResponseSubmitted
848
1025
  }) => {
849
- const [selectedOption, setSelectedOption] = useState4(null);
1026
+ const [selectedOption, setSelectedOption] = useState5(null);
850
1027
  const params = parameters;
851
1028
  const { yesPrompt, noPrompt } = params;
852
1029
  console.log("[ConfirmInteraction] Parameters:", params);
@@ -855,8 +1032,8 @@ var ConfirmInteraction = ({
855
1032
  setSelectedOption(buttonText);
856
1033
  onResponse(value);
857
1034
  };
858
- return /* @__PURE__ */ jsx7("div", { className: "mt-2 mb-4", children: /* @__PURE__ */ jsxs5("div", { className: "flex space-x-2", children: [
859
- /* @__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(
860
1037
  "button",
861
1038
  {
862
1039
  onClick: () => handleOptionClick(true, yesPrompt),
@@ -865,7 +1042,7 @@ var ConfirmInteraction = ({
865
1042
  children: yesPrompt
866
1043
  }
867
1044
  ),
868
- /* @__PURE__ */ jsx7(
1045
+ /* @__PURE__ */ jsx8(
869
1046
  "button",
870
1047
  {
871
1048
  onClick: () => handleOptionClick(false, noPrompt),
@@ -879,16 +1056,16 @@ var ConfirmInteraction = ({
879
1056
  var ConfirmInteraction_default = ConfirmInteraction;
880
1057
 
881
1058
  // src/ui/react/components/interactive/SelectInteraction.tsx
882
- import { useState as useState5, useEffect as useEffect3 } from "react";
883
- 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";
884
1061
  var SelectInteraction = ({
885
1062
  parameters,
886
1063
  onResponse,
887
1064
  isResponseSubmitted,
888
1065
  message
889
1066
  }) => {
890
- const [selectedOption, setSelectedOption] = useState5(null);
891
- const [customOption, setCustomOption] = useState5(null);
1067
+ const [selectedOption, setSelectedOption] = useState6(null);
1068
+ const [customOption, setCustomOption] = useState6(null);
892
1069
  const params = parameters;
893
1070
  const { question, options, placeholder } = params;
894
1071
  useEffect3(() => {
@@ -906,8 +1083,8 @@ var SelectInteraction = ({
906
1083
  setCustomOption(null);
907
1084
  onResponse(option);
908
1085
  };
909
- return /* @__PURE__ */ jsxs6("div", { className: "mt-2 mb-4", children: [
910
- /* @__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(
911
1088
  "button",
912
1089
  {
913
1090
  onClick: () => handleOptionClick(option),
@@ -917,9 +1094,9 @@ var SelectInteraction = ({
917
1094
  },
918
1095
  index
919
1096
  )) }),
920
- 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: [
921
1098
  "User provided custom option: ",
922
- /* @__PURE__ */ jsxs6("span", { className: "font-semibold", children: [
1099
+ /* @__PURE__ */ jsxs7("span", { className: "font-semibold", children: [
923
1100
  '"',
924
1101
  customOption,
925
1102
  '"'
@@ -930,20 +1107,20 @@ var SelectInteraction = ({
930
1107
  var SelectInteraction_default = SelectInteraction;
931
1108
 
932
1109
  // src/ui/react/components/interactive/FormInteraction.tsx
933
- 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";
934
1111
  import { ChevronDownIcon, ChevronUpIcon } from "lucide-react";
935
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1112
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
936
1113
  var FormInteraction = ({
937
1114
  parameters,
938
1115
  onResponse,
939
1116
  isResponseSubmitted,
940
1117
  submittedValues
941
1118
  }) => {
942
- const [isModalOpen, setIsModalOpen] = useState6(false);
943
- const [formValues, setFormValues] = useState6({});
944
- const [isExpanded, setIsExpanded] = useState6(false);
945
- const [parsedFields, setParsedFields] = useState6([]);
946
- 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);
947
1124
  const parseParameters = () => {
948
1125
  const { prompt, description, submitText = "Submit", cancelText = "Cancel" } = parameters;
949
1126
  let fieldsArray = [];
@@ -1052,12 +1229,12 @@ var FormInteraction = ({
1052
1229
  case "email":
1053
1230
  case "number":
1054
1231
  case "password":
1055
- return /* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-center space-x-4", children: [
1056
- /* @__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: [
1057
1234
  label,
1058
- required && /* @__PURE__ */ jsx9("span", { className: "text-red-500", children: "*" })
1235
+ required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
1059
1236
  ] }),
1060
- /* @__PURE__ */ jsx9(
1237
+ /* @__PURE__ */ jsx10(
1061
1238
  "input",
1062
1239
  {
1063
1240
  type: type === "string" ? "text" : type,
@@ -1073,12 +1250,12 @@ var FormInteraction = ({
1073
1250
  )
1074
1251
  ] }, name);
1075
1252
  case "textarea":
1076
- return /* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-start space-x-4", children: [
1077
- /* @__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: [
1078
1255
  label,
1079
- required && /* @__PURE__ */ jsx9("span", { className: "text-red-500", children: "*" })
1256
+ required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
1080
1257
  ] }),
1081
- /* @__PURE__ */ jsx9(
1258
+ /* @__PURE__ */ jsx10(
1082
1259
  "textarea",
1083
1260
  {
1084
1261
  id: name,
@@ -1094,12 +1271,12 @@ var FormInteraction = ({
1094
1271
  )
1095
1272
  ] }, name);
1096
1273
  case "select":
1097
- return /* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-center space-x-4", children: [
1098
- /* @__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: [
1099
1276
  label,
1100
- required && /* @__PURE__ */ jsx9("span", { className: "text-red-500", children: "*" })
1277
+ required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
1101
1278
  ] }),
1102
- /* @__PURE__ */ jsxs7(
1279
+ /* @__PURE__ */ jsxs8(
1103
1280
  "select",
1104
1281
  {
1105
1282
  id: name,
@@ -1110,17 +1287,17 @@ var FormInteraction = ({
1110
1287
  disabled: isResponseSubmitted,
1111
1288
  className: "flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1112
1289
  children: [
1113
- /* @__PURE__ */ jsx9("option", { value: "", disabled: true, children: placeholder || "Select an option" }),
1114
- 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))
1115
1292
  ]
1116
1293
  }
1117
1294
  )
1118
1295
  ] }, name);
1119
1296
  case "checkbox":
1120
- return /* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-center space-x-4", children: [
1121
- /* @__PURE__ */ jsx9("div", { className: "min-w-[120px]" }),
1122
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center", children: [
1123
- /* @__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(
1124
1301
  "input",
1125
1302
  {
1126
1303
  type: "checkbox",
@@ -1133,20 +1310,20 @@ var FormInteraction = ({
1133
1310
  className: "h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
1134
1311
  }
1135
1312
  ),
1136
- /* @__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: [
1137
1314
  label,
1138
- required && /* @__PURE__ */ jsx9("span", { className: "text-red-500", children: "*" })
1315
+ required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
1139
1316
  ] })
1140
1317
  ] })
1141
1318
  ] }, name);
1142
1319
  case "radio":
1143
- return /* @__PURE__ */ jsxs7("div", { className: "mb-4 flex space-x-4", children: [
1144
- /* @__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: [
1145
1322
  label,
1146
- required && /* @__PURE__ */ jsx9("span", { className: "text-red-500", children: "*" })
1323
+ required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
1147
1324
  ] }),
1148
- /* @__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: [
1149
- /* @__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(
1150
1327
  "input",
1151
1328
  {
1152
1329
  id: `${name}-${index}`,
@@ -1160,7 +1337,7 @@ var FormInteraction = ({
1160
1337
  className: "h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500"
1161
1338
  }
1162
1339
  ),
1163
- /* @__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 })
1164
1341
  ] }, index)) })
1165
1342
  ] }, name);
1166
1343
  default:
@@ -1168,27 +1345,27 @@ var FormInteraction = ({
1168
1345
  }
1169
1346
  };
1170
1347
  if (isResponseSubmitted) {
1171
- return /* @__PURE__ */ jsxs7("div", { className: "mt-2 bg-gray-50 p-3 rounded-md border border-gray-200", children: [
1172
- /* @__PURE__ */ jsxs7("div", { className: "flex justify-between items-center cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
1173
- /* @__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: [
1174
1351
  isExpanded ? "Hide" : "Show",
1175
1352
  " Form Responses"
1176
1353
  ] }),
1177
- 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" })
1178
1355
  ] }),
1179
- isExpanded && /* @__PURE__ */ jsx9("div", { className: "mt-2 space-y-2", children: parsedFields.map((field) => /* @__PURE__ */ jsxs7("div", { className: "flex", children: [
1180
- /* @__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: [
1181
1358
  field.label,
1182
1359
  ":"
1183
1360
  ] }),
1184
- /* @__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" })
1185
1362
  ] }, field.name)) })
1186
1363
  ] });
1187
1364
  }
1188
- 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: [
1189
1366
  parsedFields.map((field) => renderField(field)),
1190
- /* @__PURE__ */ jsxs7("div", { ref: formButtonsRef, className: "flex justify-end mt-4 space-x-2", children: [
1191
- /* @__PURE__ */ jsx9(
1367
+ /* @__PURE__ */ jsxs8("div", { ref: formButtonsRef, className: "flex justify-end mt-4 space-x-2", children: [
1368
+ /* @__PURE__ */ jsx10(
1192
1369
  "button",
1193
1370
  {
1194
1371
  type: "button",
@@ -1198,7 +1375,7 @@ var FormInteraction = ({
1198
1375
  children: params.cancelText
1199
1376
  }
1200
1377
  ),
1201
- /* @__PURE__ */ jsx9(
1378
+ /* @__PURE__ */ jsx10(
1202
1379
  "button",
1203
1380
  {
1204
1381
  type: "submit",
@@ -1213,12 +1390,12 @@ var FormInteraction = ({
1213
1390
  var FormInteraction_default = FormInteraction;
1214
1391
 
1215
1392
  // src/ui/react/components/interactive/PresentInteraction.tsx
1216
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
1393
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
1217
1394
  var ReactMarkdown2;
1218
1395
  try {
1219
1396
  ReactMarkdown2 = __require("react-markdown");
1220
1397
  } catch (error) {
1221
- ReactMarkdown2 = ({ children }) => /* @__PURE__ */ jsx10("div", { className: "whitespace-pre-wrap", children });
1398
+ ReactMarkdown2 = ({ children }) => /* @__PURE__ */ jsx11("div", { className: "whitespace-pre-wrap", children });
1222
1399
  }
1223
1400
  var PresentInteraction = ({
1224
1401
  parameters
@@ -1256,15 +1433,15 @@ var PresentInteraction = ({
1256
1433
  }
1257
1434
  };
1258
1435
  const styles = getLevelStyles();
1259
- return /* @__PURE__ */ jsxs8("div", { className: `mt-2 mb-4 p-4 ${styles.container} border rounded-md`, children: [
1260
- title && /* @__PURE__ */ jsx10("div", { className: `font-medium ${styles.title} mb-2`, children: title }),
1261
- /* @__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 }) })
1262
1439
  ] });
1263
1440
  };
1264
1441
  var PresentInteraction_default = PresentInteraction;
1265
1442
 
1266
1443
  // src/ui/react/components/interactive/InteractiveMessageHandler.tsx
1267
- import { jsx as jsx11 } from "react/jsx-runtime";
1444
+ import { jsx as jsx12 } from "react/jsx-runtime";
1268
1445
  var InteractiveMessageHandler = ({
1269
1446
  message,
1270
1447
  onResponse,
@@ -1275,7 +1452,7 @@ var InteractiveMessageHandler = ({
1275
1452
  const submittedResponse = parentMessage == null ? void 0 : parentMessage.responseValue;
1276
1453
  switch (functionType) {
1277
1454
  case "confirm":
1278
- return /* @__PURE__ */ jsx11(
1455
+ return /* @__PURE__ */ jsx12(
1279
1456
  ConfirmInteraction_default,
1280
1457
  {
1281
1458
  parameters,
@@ -1284,7 +1461,7 @@ var InteractiveMessageHandler = ({
1284
1461
  }
1285
1462
  );
1286
1463
  case "select":
1287
- return /* @__PURE__ */ jsx11(
1464
+ return /* @__PURE__ */ jsx12(
1288
1465
  SelectInteraction_default,
1289
1466
  {
1290
1467
  parameters,
@@ -1294,7 +1471,7 @@ var InteractiveMessageHandler = ({
1294
1471
  }
1295
1472
  );
1296
1473
  case "form":
1297
- return /* @__PURE__ */ jsx11(
1474
+ return /* @__PURE__ */ jsx12(
1298
1475
  FormInteraction_default,
1299
1476
  {
1300
1477
  parameters,
@@ -1304,7 +1481,7 @@ var InteractiveMessageHandler = ({
1304
1481
  }
1305
1482
  );
1306
1483
  case "present":
1307
- return /* @__PURE__ */ jsx11(
1484
+ return /* @__PURE__ */ jsx12(
1308
1485
  PresentInteraction_default,
1309
1486
  {
1310
1487
  parameters
@@ -1321,7 +1498,7 @@ var InteractiveMessageHandler_default = InteractiveMessageHandler;
1321
1498
 
1322
1499
  // src/ui/react/components/ChatMessageList.tsx
1323
1500
  import { InformationCircleIcon } from "@heroicons/react/24/outline";
1324
- import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
1501
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1325
1502
  var ChatMessageList = ({
1326
1503
  chatHistory,
1327
1504
  isProcessing,
@@ -1330,9 +1507,9 @@ var ChatMessageList = ({
1330
1507
  getContextExample,
1331
1508
  onInteractiveResponse
1332
1509
  }) => {
1333
- const chatContainerRef = useRef5(null);
1334
- const lastMessageRef = useRef5(null);
1335
- const processingIndicatorRef = useRef5(null);
1510
+ const chatContainerRef = useRef6(null);
1511
+ const lastMessageRef = useRef6(null);
1512
+ const processingIndicatorRef = useRef6(null);
1336
1513
  useEffect5(() => {
1337
1514
  if (isProcessing && processingIndicatorRef.current) {
1338
1515
  processingIndicatorRef.current.scrollIntoView({ behavior: "smooth" });
@@ -1349,15 +1526,15 @@ var ChatMessageList = ({
1349
1526
  onInteractiveResponse(messageId, response);
1350
1527
  }
1351
1528
  };
1352
- return /* @__PURE__ */ jsxs9(
1529
+ return /* @__PURE__ */ jsxs10(
1353
1530
  "div",
1354
1531
  {
1355
1532
  ref: chatContainerRef,
1356
1533
  className: "flex-1 overflow-y-auto p-4 space-y-8 bg-gray-50",
1357
1534
  children: [
1358
- chatHistory.length === 0 && !isProcessing && /* @__PURE__ */ jsxs9("div", { className: "text-center py-8", children: [
1359
- /* @__PURE__ */ jsx12("h3", { className: "text-lg font-medium text-gray-700 mb-2", children: "How can I help you today?" }),
1360
- /* @__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: [
1361
1538
  "Try asking me something like ",
1362
1539
  getContextExample()
1363
1540
  ] })
@@ -1366,14 +1543,14 @@ var ChatMessageList = ({
1366
1543
  const isLastMessage = index === chatHistory.length - 1;
1367
1544
  const isUser = message.role === "user";
1368
1545
  const isError = message.role === "error";
1369
- return /* @__PURE__ */ jsxs9(
1546
+ return /* @__PURE__ */ jsxs10(
1370
1547
  "div",
1371
1548
  {
1372
1549
  ref: isLastMessage ? lastMessageRef : void 0,
1373
1550
  className: `flex flex-col w-full ${isUser ? "items-end" : "items-start"}`,
1374
1551
  children: [
1375
- /* @__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()}` : "" }),
1376
- /* @__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(
1377
1554
  InteractiveMessageHandler_default,
1378
1555
  {
1379
1556
  message: message.interactiveData,
@@ -1385,16 +1562,16 @@ var ChatMessageList = ({
1385
1562
  isResponseSubmitted: !!message.isResponseSubmitted,
1386
1563
  parentMessage: message
1387
1564
  }
1388
- ) }) : /* @__PURE__ */ jsx12(
1565
+ ) }) : /* @__PURE__ */ jsx13(
1389
1566
  MessageBubble,
1390
1567
  {
1391
1568
  message,
1392
1569
  isUser
1393
1570
  }
1394
1571
  ) }),
1395
- isUser && message.interactive && /* @__PURE__ */ jsxs9("div", { className: "flex items-center mt-1 space-x-1 text-xs text-gray-500 italic", children: [
1396
- /* @__PURE__ */ jsx12(InformationCircleIcon, { className: "h-3 w-3 text-blue-400" }),
1397
- /* @__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: [
1398
1575
  message.request === "form" && "Response to form submission",
1399
1576
  message.request === "select" && "Response to selection prompt",
1400
1577
  message.request === "confirm" && "Response to confirmation prompt"
@@ -1405,29 +1582,29 @@ var ChatMessageList = ({
1405
1582
  message.id || `message-${index}`
1406
1583
  );
1407
1584
  }),
1408
- isProcessing && /* @__PURE__ */ jsx12(
1585
+ isProcessing && /* @__PURE__ */ jsx13(
1409
1586
  "div",
1410
1587
  {
1411
1588
  ref: processingIndicatorRef,
1412
1589
  className: "flex justify-start my-4",
1413
- 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: [
1414
- /* @__PURE__ */ jsx12("span", { className: "text-sm", children: processingHint }),
1415
- /* @__PURE__ */ jsxs9("span", { className: "ml-2 flex space-x-1", children: [
1416
- /* @__PURE__ */ jsx12("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0ms" } }),
1417
- /* @__PURE__ */ jsx12("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "150ms" } }),
1418
- /* @__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" } })
1419
1596
  ] })
1420
1597
  ] }) })
1421
1598
  }
1422
1599
  ),
1423
- currentTask && !currentTask.complete && /* @__PURE__ */ jsxs9("div", { className: "mt-4 bg-blue-50 border border-blue-100 rounded-lg p-3", children: [
1424
- /* @__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: [
1425
1602
  "Task in progress: Step ",
1426
1603
  currentTask.currentStep,
1427
1604
  " of ",
1428
1605
  currentTask.steps
1429
1606
  ] }),
1430
- /* @__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(
1431
1608
  "div",
1432
1609
  {
1433
1610
  className: "bg-blue-500 h-2 rounded-full",
@@ -1442,34 +1619,34 @@ var ChatMessageList = ({
1442
1619
 
1443
1620
  // src/ui/react/components/ConnectionStatus.tsx
1444
1621
  import { Wifi, WifiOff, RefreshCw } from "lucide-react";
1445
- import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1622
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1446
1623
  var ConnectionStatus = ({
1447
1624
  connectionStatus,
1448
1625
  onReconnect
1449
1626
  }) => {
1450
- return /* @__PURE__ */ jsxs10("div", { className: "bg-amber-100 connection-status flex items-center justify-between px-4 py-1 text-xs", children: [
1451
- /* @__PURE__ */ jsx13("div", { className: "text-gray-700 font-medium", children: "You are talking with your personal Content Strategist" }),
1452
- connectionStatus === "connected" && /* @__PURE__ */ jsxs10("div", { className: "flex items-center text-green-600", children: [
1453
- /* @__PURE__ */ jsx13(Wifi, { className: "w-3 h-3 mr-1" }),
1454
- /* @__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" })
1455
1632
  ] }),
1456
- connectionStatus === "reconnecting" && /* @__PURE__ */ jsxs10("div", { className: "flex items-center text-amber-600", children: [
1457
- /* @__PURE__ */ jsx13(RefreshCw, { className: "w-3 h-3 mr-1 animate-spin" }),
1458
- /* @__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..." })
1459
1636
  ] }),
1460
- connectionStatus === "disconnected" && /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
1461
- /* @__PURE__ */ jsxs10("div", { className: "text-red-600 flex items-center", children: [
1462
- /* @__PURE__ */ jsx13(WifiOff, { className: "w-3 h-3 mr-1" }),
1463
- /* @__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" })
1464
1641
  ] }),
1465
- /* @__PURE__ */ jsxs10(
1642
+ /* @__PURE__ */ jsxs11(
1466
1643
  "button",
1467
1644
  {
1468
1645
  onClick: onReconnect,
1469
1646
  className: "text-blue-600 hover:text-blue-800 flex items-center",
1470
1647
  children: [
1471
- /* @__PURE__ */ jsx13(RefreshCw, { className: "w-3 h-3 mr-1" }),
1472
- /* @__PURE__ */ jsx13("span", { children: "Reconnect" })
1648
+ /* @__PURE__ */ jsx14(RefreshCw, { className: "w-3 h-3 mr-1" }),
1649
+ /* @__PURE__ */ jsx14("span", { children: "Reconnect" })
1473
1650
  ]
1474
1651
  }
1475
1652
  )
@@ -1478,7 +1655,7 @@ var ConnectionStatus = ({
1478
1655
  };
1479
1656
 
1480
1657
  // src/ui/react/components/Spinner.tsx
1481
- import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1658
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1482
1659
  var Spinner = ({
1483
1660
  size = "md",
1484
1661
  className = "",
@@ -1490,7 +1667,7 @@ var Spinner = ({
1490
1667
  lg: "h-8 w-8",
1491
1668
  xl: "h-12 w-12"
1492
1669
  };
1493
- return /* @__PURE__ */ jsxs11(
1670
+ return /* @__PURE__ */ jsxs12(
1494
1671
  "svg",
1495
1672
  {
1496
1673
  className: `animate-spin ${sizeClasses[size]} ${color} ${className}`,
@@ -1498,7 +1675,7 @@ var Spinner = ({
1498
1675
  fill: "none",
1499
1676
  viewBox: "0 0 24 24",
1500
1677
  children: [
1501
- /* @__PURE__ */ jsx14(
1678
+ /* @__PURE__ */ jsx15(
1502
1679
  "circle",
1503
1680
  {
1504
1681
  className: "opacity-25",
@@ -1509,7 +1686,7 @@ var Spinner = ({
1509
1686
  strokeWidth: "4"
1510
1687
  }
1511
1688
  ),
1512
- /* @__PURE__ */ jsx14(
1689
+ /* @__PURE__ */ jsx15(
1513
1690
  "path",
1514
1691
  {
1515
1692
  className: "opacity-75",