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