@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.
- package/dist/ui/react/components/index.cjs +423 -246
- package/dist/ui/react/components/index.cjs.map +1 -1
- package/dist/ui/react/components/index.d.cts +1 -0
- package/dist/ui/react/components/index.d.ts +1 -0
- package/dist/ui/react/components/index.js +410 -233
- package/dist/ui/react/components/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -148,19 +148,174 @@ function ChatHeader({
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
// src/ui/react/components/ChatInputArea.tsx
|
|
151
|
-
import { useState as
|
|
152
|
-
import {
|
|
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/
|
|
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] =
|
|
158
|
-
const [isSimulated, setIsSimulated] =
|
|
159
|
-
const [blob, setBlob] =
|
|
160
|
-
const [error, setError] =
|
|
161
|
-
const mediaRecorderRef =
|
|
162
|
-
const chunksRef =
|
|
163
|
-
const
|
|
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 =
|
|
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
|
|
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] =
|
|
269
|
-
const [voiceTrigger, setVoiceTrigger] =
|
|
270
|
-
const [isTranscribing, setIsTranscribing] =
|
|
271
|
-
const [voiceError, setVoiceError] =
|
|
272
|
-
const [isFocused, setIsFocused] =
|
|
273
|
-
const [showDebug, setShowDebug] =
|
|
274
|
-
const [logs, setLogs] =
|
|
275
|
-
const tapCountRef =
|
|
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 =
|
|
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 =
|
|
313
|
-
const measurementRef =
|
|
314
|
-
const pendingSelectionRef =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
509
|
+
const voiceConfigRef = useRef3(voiceConfig);
|
|
335
510
|
useEffect2(() => {
|
|
336
511
|
voiceConfigRef.current = voiceConfig;
|
|
337
512
|
}, [voiceConfig]);
|
|
338
|
-
const triggerChange =
|
|
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 =
|
|
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 =
|
|
545
|
+
const handleVoiceResult = useCallback3((text, isFinal) => {
|
|
371
546
|
if (isFinal) {
|
|
372
547
|
insertTextAtCursor(text);
|
|
373
548
|
}
|
|
374
549
|
}, [insertTextAtCursor]);
|
|
375
|
-
const handleVoiceEnd =
|
|
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__ */
|
|
487
|
-
showDebug && /* @__PURE__ */
|
|
488
|
-
/* @__PURE__ */
|
|
489
|
-
/* @__PURE__ */
|
|
490
|
-
/* @__PURE__ */
|
|
491
|
-
/* @__PURE__ */
|
|
492
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
499
|
-
logs.length === 0 && /* @__PURE__ */
|
|
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__ */
|
|
502
|
-
voiceConfig && /* @__PURE__ */
|
|
503
|
-
|
|
676
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
|
|
677
|
+
voiceConfig && /* @__PURE__ */ jsx6(
|
|
678
|
+
VoiceInputButton,
|
|
504
679
|
{
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
575
|
-
isSending && /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
629
|
-
/* @__PURE__ */
|
|
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 ? "
|
|
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
|
|
639
|
-
import { MicrophoneIcon as
|
|
640
|
-
import { jsx as
|
|
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] =
|
|
654
|
-
const [voiceTrigger, setVoiceTrigger] =
|
|
655
|
-
const [errorMsg, setErrorMsg] =
|
|
656
|
-
const [showDebug, setShowDebug] =
|
|
657
|
-
const [logs, setLogs] =
|
|
658
|
-
const tapCountRef =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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__ */
|
|
956
|
+
let Icon = /* @__PURE__ */ jsx7(MicrophoneIcon3, { className: "h-5 w-5" });
|
|
787
957
|
if (isListening) {
|
|
788
958
|
bgColor = "bg-orange-500";
|
|
789
|
-
label = "Listening
|
|
790
|
-
Icon = /* @__PURE__ */
|
|
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__ */
|
|
795
|
-
/* @__PURE__ */
|
|
796
|
-
/* @__PURE__ */
|
|
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__ */
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
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__ */
|
|
808
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
816
|
-
logs.length === 0 && /* @__PURE__ */
|
|
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__ */
|
|
995
|
+
/* @__PURE__ */ jsxs5(
|
|
819
996
|
"button",
|
|
820
997
|
{
|
|
821
|
-
|
|
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
|
|
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__ */
|
|
830
|
-
/* @__PURE__ */
|
|
831
|
-
errorMsg && /* @__PURE__ */
|
|
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
|
|
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
|
|
843
|
-
import { jsx as
|
|
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] =
|
|
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__ */
|
|
859
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
|
883
|
-
import { jsx as
|
|
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] =
|
|
891
|
-
const [customOption, setCustomOption] =
|
|
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__ */
|
|
910
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
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
|
|
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] =
|
|
943
|
-
const [formValues, setFormValues] =
|
|
944
|
-
const [isExpanded, setIsExpanded] =
|
|
945
|
-
const [parsedFields, setParsedFields] =
|
|
946
|
-
const formButtonsRef =
|
|
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__ */
|
|
1056
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1235
|
+
required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
|
|
1059
1236
|
] }),
|
|
1060
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1077
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1256
|
+
required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
|
|
1080
1257
|
] }),
|
|
1081
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1098
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1277
|
+
required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
|
|
1101
1278
|
] }),
|
|
1102
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1114
|
-
options == null ? void 0 : options.map((option, index) => /* @__PURE__ */
|
|
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__ */
|
|
1121
|
-
/* @__PURE__ */
|
|
1122
|
-
/* @__PURE__ */
|
|
1123
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1313
|
+
/* @__PURE__ */ jsxs8("label", { htmlFor: name, className: "ml-2 text-sm text-gray-700", children: [
|
|
1137
1314
|
label,
|
|
1138
|
-
required && /* @__PURE__ */
|
|
1315
|
+
required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
|
|
1139
1316
|
] })
|
|
1140
1317
|
] })
|
|
1141
1318
|
] }, name);
|
|
1142
1319
|
case "radio":
|
|
1143
|
-
return /* @__PURE__ */
|
|
1144
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1323
|
+
required && /* @__PURE__ */ jsx10("span", { className: "text-red-500", children: "*" })
|
|
1147
1324
|
] }),
|
|
1148
|
-
/* @__PURE__ */
|
|
1149
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
1172
|
-
/* @__PURE__ */
|
|
1173
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
1180
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1191
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
1260
|
-
title && /* @__PURE__ */
|
|
1261
|
-
/* @__PURE__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
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 =
|
|
1334
|
-
const lastMessageRef =
|
|
1335
|
-
const processingIndicatorRef =
|
|
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__ */
|
|
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__ */
|
|
1359
|
-
/* @__PURE__ */
|
|
1360
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
1376
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1565
|
+
) }) : /* @__PURE__ */ jsx13(
|
|
1389
1566
|
MessageBubble,
|
|
1390
1567
|
{
|
|
1391
1568
|
message,
|
|
1392
1569
|
isUser
|
|
1393
1570
|
}
|
|
1394
1571
|
) }),
|
|
1395
|
-
isUser && message.interactive && /* @__PURE__ */
|
|
1396
|
-
/* @__PURE__ */
|
|
1397
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1585
|
+
isProcessing && /* @__PURE__ */ jsx13(
|
|
1409
1586
|
"div",
|
|
1410
1587
|
{
|
|
1411
1588
|
ref: processingIndicatorRef,
|
|
1412
1589
|
className: "flex justify-start my-4",
|
|
1413
|
-
children: /* @__PURE__ */
|
|
1414
|
-
/* @__PURE__ */
|
|
1415
|
-
/* @__PURE__ */
|
|
1416
|
-
/* @__PURE__ */
|
|
1417
|
-
/* @__PURE__ */
|
|
1418
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1424
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
1451
|
-
/* @__PURE__ */
|
|
1452
|
-
connectionStatus === "connected" && /* @__PURE__ */
|
|
1453
|
-
/* @__PURE__ */
|
|
1454
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1457
|
-
/* @__PURE__ */
|
|
1458
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1461
|
-
/* @__PURE__ */
|
|
1462
|
-
/* @__PURE__ */
|
|
1463
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
1472
|
-
/* @__PURE__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1689
|
+
/* @__PURE__ */ jsx15(
|
|
1513
1690
|
"path",
|
|
1514
1691
|
{
|
|
1515
1692
|
className: "opacity-75",
|