@contentgrowth/llm-service 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ui/react/components/index.cjs +429 -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 +416 -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,13 +886,14 @@ 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) => {
|
|
896
|
+
var _a2;
|
|
740
897
|
setVoiceTrigger(null);
|
|
741
898
|
setIsTranscribing(true);
|
|
742
899
|
setErrorMsg(null);
|
|
@@ -760,11 +917,13 @@ var TapToTalk = ({
|
|
|
760
917
|
} else {
|
|
761
918
|
setIsTranscribing(false);
|
|
762
919
|
}
|
|
920
|
+
(_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a2.call(voiceConfig);
|
|
763
921
|
});
|
|
764
922
|
const isListening = !!voiceTrigger || customRecorder.isRecording;
|
|
765
923
|
const isActive = isListening || isTranscribing;
|
|
766
|
-
const processingRef = (0,
|
|
924
|
+
const processingRef = (0, import_react6.useRef)(false);
|
|
767
925
|
const toggleVoice = async () => {
|
|
926
|
+
var _a2, _b, _c;
|
|
768
927
|
if (processingRef.current) {
|
|
769
928
|
console.log("[TapToTalk] toggleVoice ignored - processing");
|
|
770
929
|
return;
|
|
@@ -797,17 +956,20 @@ var TapToTalk = ({
|
|
|
797
956
|
console.log("[TapToTalk] Stopping voice...");
|
|
798
957
|
customRecorder.stop();
|
|
799
958
|
setVoiceTrigger(null);
|
|
959
|
+
(_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a2.call(voiceConfig);
|
|
800
960
|
} else {
|
|
801
961
|
console.log("[TapToTalk] Starting voice...");
|
|
802
962
|
setErrorMsg(null);
|
|
803
963
|
onFocusTarget == null ? void 0 : onFocusTarget();
|
|
804
964
|
setVoiceTrigger("click");
|
|
965
|
+
(_b = voiceConfig == null ? void 0 : voiceConfig.onVoiceStart) == null ? void 0 : _b.call(voiceConfig);
|
|
805
966
|
try {
|
|
806
967
|
await customRecorder.start();
|
|
807
968
|
} catch (e) {
|
|
808
969
|
console.error("[TapToTalk] Custom recorder failed:", e);
|
|
809
970
|
setErrorMsg("Mic access denied");
|
|
810
971
|
setVoiceTrigger(null);
|
|
972
|
+
(_c = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _c.call(voiceConfig);
|
|
811
973
|
}
|
|
812
974
|
}
|
|
813
975
|
} finally {
|
|
@@ -816,54 +978,75 @@ var TapToTalk = ({
|
|
|
816
978
|
}, 300);
|
|
817
979
|
}
|
|
818
980
|
};
|
|
981
|
+
const { handlers, isDragging, isPressed } = useDragCancel({
|
|
982
|
+
isListening: !!voiceTrigger,
|
|
983
|
+
onCancel: () => {
|
|
984
|
+
var _a2;
|
|
985
|
+
console.log("[TapToTalk] Gesture Cancel");
|
|
986
|
+
customRecorder.cancel();
|
|
987
|
+
setVoiceTrigger(null);
|
|
988
|
+
(_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a2.call(voiceConfig);
|
|
989
|
+
},
|
|
990
|
+
onCommit: () => {
|
|
991
|
+
toggleVoice();
|
|
992
|
+
},
|
|
993
|
+
threshold: 30
|
|
994
|
+
});
|
|
819
995
|
let bgColor = accentColor;
|
|
820
996
|
let label = "Tap to Talk";
|
|
821
|
-
let Icon = /* @__PURE__ */ (0,
|
|
997
|
+
let Icon = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_outline3.MicrophoneIcon, { className: "h-5 w-5" });
|
|
822
998
|
if (isListening) {
|
|
823
999
|
bgColor = "bg-orange-500";
|
|
824
|
-
label = "Listening
|
|
825
|
-
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" });
|
|
826
1002
|
} else if (isTranscribing) {
|
|
827
1003
|
bgColor = "bg-indigo-600";
|
|
828
1004
|
label = "Transcribing ...";
|
|
829
|
-
Icon = /* @__PURE__ */ (0,
|
|
830
|
-
/* @__PURE__ */ (0,
|
|
831
|
-
/* @__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" })
|
|
832
1008
|
] });
|
|
833
1009
|
}
|
|
834
|
-
return /* @__PURE__ */ (0,
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
1010
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col w-full relative items-center", children: [
|
|
1011
|
+
isListening && !isTranscribing && isPressed && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `absolute bottom-full mb-6 left-1/2 -translate-x-1/2 px-4 py-2 rounded-full text-sm font-semibold whitespace-nowrap shadow-xl transition-all duration-200 z-50 flex items-center gap-2 pointer-events-none transform
|
|
1012
|
+
${isDragging ? "bg-red-500 text-white scale-110" : "bg-white text-red-500 border border-red-100"}`, children: [
|
|
1013
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `transition-transform duration-300 ${isDragging ? "rotate-180" : ""}`, children: isDragging ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_outline3.XMarkIcon, { className: "w-5 h-5" }) : "\u2191" }),
|
|
1014
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: isDragging ? "Release to Cancel" : "Drag here to cancel" }),
|
|
1015
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `absolute top-full left-1/2 -translate-x-1/2 border-8 border-transparent transition-colors duration-200
|
|
1016
|
+
${isDragging ? "border-t-red-500" : "border-t-white"}` })
|
|
1017
|
+
] }),
|
|
1018
|
+
showDebug && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto", children: [
|
|
1019
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
|
|
1020
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Debug Logs" }),
|
|
1021
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex gap-2", children: [
|
|
1022
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { onClick: (e) => {
|
|
840
1023
|
e.stopPropagation();
|
|
841
1024
|
copyLogs();
|
|
842
|
-
}, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ (0,
|
|
843
|
-
/* @__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) => {
|
|
844
1027
|
e.stopPropagation();
|
|
845
1028
|
copyLogs();
|
|
846
1029
|
setShowDebug(false);
|
|
847
|
-
}, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ (0,
|
|
1030
|
+
}, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_outline3.XMarkIcon, { className: "w-4 h-4" }) })
|
|
848
1031
|
] })
|
|
849
1032
|
] }),
|
|
850
|
-
logs.map((log, i) => /* @__PURE__ */ (0,
|
|
851
|
-
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..." })
|
|
852
1035
|
] }),
|
|
853
|
-
/* @__PURE__ */ (0,
|
|
1036
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
854
1037
|
"button",
|
|
855
1038
|
{
|
|
856
|
-
|
|
1039
|
+
...handlers,
|
|
857
1040
|
disabled: disabled || isTranscribing && !isListening,
|
|
858
|
-
className: `flex items-center justify-center gap-3 px-6 py-3 rounded-xl transition-all duration-300 w-full font-medium shadow-md
|
|
1041
|
+
className: `flex items-center justify-center gap-3 px-6 py-3 rounded-xl transition-all duration-300 w-full font-medium shadow-md touch-none select-none
|
|
859
1042
|
${bgColor} text-white
|
|
860
1043
|
${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
|
|
861
1044
|
${className}`,
|
|
862
1045
|
title: label,
|
|
863
1046
|
children: [
|
|
864
|
-
/* @__PURE__ */ (0,
|
|
865
|
-
/* @__PURE__ */ (0,
|
|
866
|
-
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 })
|
|
867
1050
|
]
|
|
868
1051
|
}
|
|
869
1052
|
)
|
|
@@ -871,17 +1054,17 @@ var TapToTalk = ({
|
|
|
871
1054
|
};
|
|
872
1055
|
|
|
873
1056
|
// src/ui/react/components/ChatMessageList.tsx
|
|
874
|
-
var
|
|
1057
|
+
var import_react10 = require("react");
|
|
875
1058
|
|
|
876
1059
|
// src/ui/react/components/interactive/ConfirmInteraction.tsx
|
|
877
|
-
var
|
|
878
|
-
var
|
|
1060
|
+
var import_react7 = require("react");
|
|
1061
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
879
1062
|
var ConfirmInteraction = ({
|
|
880
1063
|
parameters,
|
|
881
1064
|
onResponse,
|
|
882
1065
|
isResponseSubmitted
|
|
883
1066
|
}) => {
|
|
884
|
-
const [selectedOption, setSelectedOption] = (0,
|
|
1067
|
+
const [selectedOption, setSelectedOption] = (0, import_react7.useState)(null);
|
|
885
1068
|
const params = parameters;
|
|
886
1069
|
const { yesPrompt, noPrompt } = params;
|
|
887
1070
|
console.log("[ConfirmInteraction] Parameters:", params);
|
|
@@ -890,8 +1073,8 @@ var ConfirmInteraction = ({
|
|
|
890
1073
|
setSelectedOption(buttonText);
|
|
891
1074
|
onResponse(value);
|
|
892
1075
|
};
|
|
893
|
-
return /* @__PURE__ */ (0,
|
|
894
|
-
/* @__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)(
|
|
895
1078
|
"button",
|
|
896
1079
|
{
|
|
897
1080
|
onClick: () => handleOptionClick(true, yesPrompt),
|
|
@@ -900,7 +1083,7 @@ var ConfirmInteraction = ({
|
|
|
900
1083
|
children: yesPrompt
|
|
901
1084
|
}
|
|
902
1085
|
),
|
|
903
|
-
/* @__PURE__ */ (0,
|
|
1086
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
904
1087
|
"button",
|
|
905
1088
|
{
|
|
906
1089
|
onClick: () => handleOptionClick(false, noPrompt),
|
|
@@ -914,19 +1097,19 @@ var ConfirmInteraction = ({
|
|
|
914
1097
|
var ConfirmInteraction_default = ConfirmInteraction;
|
|
915
1098
|
|
|
916
1099
|
// src/ui/react/components/interactive/SelectInteraction.tsx
|
|
917
|
-
var
|
|
918
|
-
var
|
|
1100
|
+
var import_react8 = require("react");
|
|
1101
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
919
1102
|
var SelectInteraction = ({
|
|
920
1103
|
parameters,
|
|
921
1104
|
onResponse,
|
|
922
1105
|
isResponseSubmitted,
|
|
923
1106
|
message
|
|
924
1107
|
}) => {
|
|
925
|
-
const [selectedOption, setSelectedOption] = (0,
|
|
926
|
-
const [customOption, setCustomOption] = (0,
|
|
1108
|
+
const [selectedOption, setSelectedOption] = (0, import_react8.useState)(null);
|
|
1109
|
+
const [customOption, setCustomOption] = (0, import_react8.useState)(null);
|
|
927
1110
|
const params = parameters;
|
|
928
1111
|
const { question, options, placeholder } = params;
|
|
929
|
-
(0,
|
|
1112
|
+
(0, import_react8.useEffect)(() => {
|
|
930
1113
|
if (isResponseSubmitted && (message == null ? void 0 : message.responseValue)) {
|
|
931
1114
|
const responseValueStr = String(message.responseValue);
|
|
932
1115
|
setSelectedOption(responseValueStr);
|
|
@@ -941,8 +1124,8 @@ var SelectInteraction = ({
|
|
|
941
1124
|
setCustomOption(null);
|
|
942
1125
|
onResponse(option);
|
|
943
1126
|
};
|
|
944
|
-
return /* @__PURE__ */ (0,
|
|
945
|
-
/* @__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)(
|
|
946
1129
|
"button",
|
|
947
1130
|
{
|
|
948
1131
|
onClick: () => handleOptionClick(option),
|
|
@@ -952,9 +1135,9 @@ var SelectInteraction = ({
|
|
|
952
1135
|
},
|
|
953
1136
|
index
|
|
954
1137
|
)) }),
|
|
955
|
-
customOption && isResponseSubmitted && /* @__PURE__ */ (0,
|
|
1138
|
+
customOption && isResponseSubmitted && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mt-2 text-sm text-amber-600 bg-amber-50 p-2 rounded", children: [
|
|
956
1139
|
"User provided custom option: ",
|
|
957
|
-
/* @__PURE__ */ (0,
|
|
1140
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "font-semibold", children: [
|
|
958
1141
|
'"',
|
|
959
1142
|
customOption,
|
|
960
1143
|
'"'
|
|
@@ -965,20 +1148,20 @@ var SelectInteraction = ({
|
|
|
965
1148
|
var SelectInteraction_default = SelectInteraction;
|
|
966
1149
|
|
|
967
1150
|
// src/ui/react/components/interactive/FormInteraction.tsx
|
|
968
|
-
var
|
|
1151
|
+
var import_react9 = require("react");
|
|
969
1152
|
var import_lucide_react = require("lucide-react");
|
|
970
|
-
var
|
|
1153
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
971
1154
|
var FormInteraction = ({
|
|
972
1155
|
parameters,
|
|
973
1156
|
onResponse,
|
|
974
1157
|
isResponseSubmitted,
|
|
975
1158
|
submittedValues
|
|
976
1159
|
}) => {
|
|
977
|
-
const [isModalOpen, setIsModalOpen] = (0,
|
|
978
|
-
const [formValues, setFormValues] = (0,
|
|
979
|
-
const [isExpanded, setIsExpanded] = (0,
|
|
980
|
-
const [parsedFields, setParsedFields] = (0,
|
|
981
|
-
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);
|
|
982
1165
|
const parseParameters = () => {
|
|
983
1166
|
const { prompt, description, submitText = "Submit", cancelText = "Cancel" } = parameters;
|
|
984
1167
|
let fieldsArray = [];
|
|
@@ -1039,7 +1222,7 @@ var FormInteraction = ({
|
|
|
1039
1222
|
};
|
|
1040
1223
|
};
|
|
1041
1224
|
const params = parseParameters();
|
|
1042
|
-
(0,
|
|
1225
|
+
(0, import_react9.useEffect)(() => {
|
|
1043
1226
|
const processedParams = parseParameters();
|
|
1044
1227
|
setParsedFields(processedParams.fields);
|
|
1045
1228
|
const initialValues = {};
|
|
@@ -1057,7 +1240,7 @@ var FormInteraction = ({
|
|
|
1057
1240
|
setIsModalOpen(true);
|
|
1058
1241
|
}
|
|
1059
1242
|
}, [parameters, isResponseSubmitted]);
|
|
1060
|
-
(0,
|
|
1243
|
+
(0, import_react9.useEffect)(() => {
|
|
1061
1244
|
if (isModalOpen && formButtonsRef.current) {
|
|
1062
1245
|
setTimeout(() => {
|
|
1063
1246
|
var _a;
|
|
@@ -1087,12 +1270,12 @@ var FormInteraction = ({
|
|
|
1087
1270
|
case "email":
|
|
1088
1271
|
case "number":
|
|
1089
1272
|
case "password":
|
|
1090
|
-
return /* @__PURE__ */ (0,
|
|
1091
|
-
/* @__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: [
|
|
1092
1275
|
label,
|
|
1093
|
-
required && /* @__PURE__ */ (0,
|
|
1276
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-red-500", children: "*" })
|
|
1094
1277
|
] }),
|
|
1095
|
-
/* @__PURE__ */ (0,
|
|
1278
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1096
1279
|
"input",
|
|
1097
1280
|
{
|
|
1098
1281
|
type: type === "string" ? "text" : type,
|
|
@@ -1108,12 +1291,12 @@ var FormInteraction = ({
|
|
|
1108
1291
|
)
|
|
1109
1292
|
] }, name);
|
|
1110
1293
|
case "textarea":
|
|
1111
|
-
return /* @__PURE__ */ (0,
|
|
1112
|
-
/* @__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: [
|
|
1113
1296
|
label,
|
|
1114
|
-
required && /* @__PURE__ */ (0,
|
|
1297
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-red-500", children: "*" })
|
|
1115
1298
|
] }),
|
|
1116
|
-
/* @__PURE__ */ (0,
|
|
1299
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1117
1300
|
"textarea",
|
|
1118
1301
|
{
|
|
1119
1302
|
id: name,
|
|
@@ -1129,12 +1312,12 @@ var FormInteraction = ({
|
|
|
1129
1312
|
)
|
|
1130
1313
|
] }, name);
|
|
1131
1314
|
case "select":
|
|
1132
|
-
return /* @__PURE__ */ (0,
|
|
1133
|
-
/* @__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: [
|
|
1134
1317
|
label,
|
|
1135
|
-
required && /* @__PURE__ */ (0,
|
|
1318
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-red-500", children: "*" })
|
|
1136
1319
|
] }),
|
|
1137
|
-
/* @__PURE__ */ (0,
|
|
1320
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1138
1321
|
"select",
|
|
1139
1322
|
{
|
|
1140
1323
|
id: name,
|
|
@@ -1145,17 +1328,17 @@ var FormInteraction = ({
|
|
|
1145
1328
|
disabled: isResponseSubmitted,
|
|
1146
1329
|
className: "flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
|
|
1147
1330
|
children: [
|
|
1148
|
-
/* @__PURE__ */ (0,
|
|
1149
|
-
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))
|
|
1150
1333
|
]
|
|
1151
1334
|
}
|
|
1152
1335
|
)
|
|
1153
1336
|
] }, name);
|
|
1154
1337
|
case "checkbox":
|
|
1155
|
-
return /* @__PURE__ */ (0,
|
|
1156
|
-
/* @__PURE__ */ (0,
|
|
1157
|
-
/* @__PURE__ */ (0,
|
|
1158
|
-
/* @__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)(
|
|
1159
1342
|
"input",
|
|
1160
1343
|
{
|
|
1161
1344
|
type: "checkbox",
|
|
@@ -1168,20 +1351,20 @@ var FormInteraction = ({
|
|
|
1168
1351
|
className: "h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
|
|
1169
1352
|
}
|
|
1170
1353
|
),
|
|
1171
|
-
/* @__PURE__ */ (0,
|
|
1354
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { htmlFor: name, className: "ml-2 text-sm text-gray-700", children: [
|
|
1172
1355
|
label,
|
|
1173
|
-
required && /* @__PURE__ */ (0,
|
|
1356
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-red-500", children: "*" })
|
|
1174
1357
|
] })
|
|
1175
1358
|
] })
|
|
1176
1359
|
] }, name);
|
|
1177
1360
|
case "radio":
|
|
1178
|
-
return /* @__PURE__ */ (0,
|
|
1179
|
-
/* @__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: [
|
|
1180
1363
|
label,
|
|
1181
|
-
required && /* @__PURE__ */ (0,
|
|
1364
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-red-500", children: "*" })
|
|
1182
1365
|
] }),
|
|
1183
|
-
/* @__PURE__ */ (0,
|
|
1184
|
-
/* @__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)(
|
|
1185
1368
|
"input",
|
|
1186
1369
|
{
|
|
1187
1370
|
id: `${name}-${index}`,
|
|
@@ -1195,7 +1378,7 @@ var FormInteraction = ({
|
|
|
1195
1378
|
className: "h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500"
|
|
1196
1379
|
}
|
|
1197
1380
|
),
|
|
1198
|
-
/* @__PURE__ */ (0,
|
|
1381
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { htmlFor: `${name}-${index}`, className: "ml-2 text-sm text-gray-700", children: option })
|
|
1199
1382
|
] }, index)) })
|
|
1200
1383
|
] }, name);
|
|
1201
1384
|
default:
|
|
@@ -1203,27 +1386,27 @@ var FormInteraction = ({
|
|
|
1203
1386
|
}
|
|
1204
1387
|
};
|
|
1205
1388
|
if (isResponseSubmitted) {
|
|
1206
|
-
return /* @__PURE__ */ (0,
|
|
1207
|
-
/* @__PURE__ */ (0,
|
|
1208
|
-
/* @__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: [
|
|
1209
1392
|
isExpanded ? "Hide" : "Show",
|
|
1210
1393
|
" Form Responses"
|
|
1211
1394
|
] }),
|
|
1212
|
-
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" })
|
|
1213
1396
|
] }),
|
|
1214
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
1215
|
-
/* @__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: [
|
|
1216
1399
|
field.label,
|
|
1217
1400
|
":"
|
|
1218
1401
|
] }),
|
|
1219
|
-
/* @__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" })
|
|
1220
1403
|
] }, field.name)) })
|
|
1221
1404
|
] });
|
|
1222
1405
|
}
|
|
1223
|
-
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: [
|
|
1224
1407
|
parsedFields.map((field) => renderField(field)),
|
|
1225
|
-
/* @__PURE__ */ (0,
|
|
1226
|
-
/* @__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)(
|
|
1227
1410
|
"button",
|
|
1228
1411
|
{
|
|
1229
1412
|
type: "button",
|
|
@@ -1233,7 +1416,7 @@ var FormInteraction = ({
|
|
|
1233
1416
|
children: params.cancelText
|
|
1234
1417
|
}
|
|
1235
1418
|
),
|
|
1236
|
-
/* @__PURE__ */ (0,
|
|
1419
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1237
1420
|
"button",
|
|
1238
1421
|
{
|
|
1239
1422
|
type: "submit",
|
|
@@ -1248,12 +1431,12 @@ var FormInteraction = ({
|
|
|
1248
1431
|
var FormInteraction_default = FormInteraction;
|
|
1249
1432
|
|
|
1250
1433
|
// src/ui/react/components/interactive/PresentInteraction.tsx
|
|
1251
|
-
var
|
|
1434
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1252
1435
|
var ReactMarkdown2;
|
|
1253
1436
|
try {
|
|
1254
1437
|
ReactMarkdown2 = require("react-markdown");
|
|
1255
1438
|
} catch (error) {
|
|
1256
|
-
ReactMarkdown2 = ({ children }) => /* @__PURE__ */ (0,
|
|
1439
|
+
ReactMarkdown2 = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "whitespace-pre-wrap", children });
|
|
1257
1440
|
}
|
|
1258
1441
|
var PresentInteraction = ({
|
|
1259
1442
|
parameters
|
|
@@ -1291,15 +1474,15 @@ var PresentInteraction = ({
|
|
|
1291
1474
|
}
|
|
1292
1475
|
};
|
|
1293
1476
|
const styles = getLevelStyles();
|
|
1294
|
-
return /* @__PURE__ */ (0,
|
|
1295
|
-
title && /* @__PURE__ */ (0,
|
|
1296
|
-
/* @__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 }) })
|
|
1297
1480
|
] });
|
|
1298
1481
|
};
|
|
1299
1482
|
var PresentInteraction_default = PresentInteraction;
|
|
1300
1483
|
|
|
1301
1484
|
// src/ui/react/components/interactive/InteractiveMessageHandler.tsx
|
|
1302
|
-
var
|
|
1485
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1303
1486
|
var InteractiveMessageHandler = ({
|
|
1304
1487
|
message,
|
|
1305
1488
|
onResponse,
|
|
@@ -1310,7 +1493,7 @@ var InteractiveMessageHandler = ({
|
|
|
1310
1493
|
const submittedResponse = parentMessage == null ? void 0 : parentMessage.responseValue;
|
|
1311
1494
|
switch (functionType) {
|
|
1312
1495
|
case "confirm":
|
|
1313
|
-
return /* @__PURE__ */ (0,
|
|
1496
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1314
1497
|
ConfirmInteraction_default,
|
|
1315
1498
|
{
|
|
1316
1499
|
parameters,
|
|
@@ -1319,7 +1502,7 @@ var InteractiveMessageHandler = ({
|
|
|
1319
1502
|
}
|
|
1320
1503
|
);
|
|
1321
1504
|
case "select":
|
|
1322
|
-
return /* @__PURE__ */ (0,
|
|
1505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1323
1506
|
SelectInteraction_default,
|
|
1324
1507
|
{
|
|
1325
1508
|
parameters,
|
|
@@ -1329,7 +1512,7 @@ var InteractiveMessageHandler = ({
|
|
|
1329
1512
|
}
|
|
1330
1513
|
);
|
|
1331
1514
|
case "form":
|
|
1332
|
-
return /* @__PURE__ */ (0,
|
|
1515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1333
1516
|
FormInteraction_default,
|
|
1334
1517
|
{
|
|
1335
1518
|
parameters,
|
|
@@ -1339,7 +1522,7 @@ var InteractiveMessageHandler = ({
|
|
|
1339
1522
|
}
|
|
1340
1523
|
);
|
|
1341
1524
|
case "present":
|
|
1342
|
-
return /* @__PURE__ */ (0,
|
|
1525
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1343
1526
|
PresentInteraction_default,
|
|
1344
1527
|
{
|
|
1345
1528
|
parameters
|
|
@@ -1355,8 +1538,8 @@ var InteractiveMessageHandler = ({
|
|
|
1355
1538
|
var InteractiveMessageHandler_default = InteractiveMessageHandler;
|
|
1356
1539
|
|
|
1357
1540
|
// src/ui/react/components/ChatMessageList.tsx
|
|
1358
|
-
var
|
|
1359
|
-
var
|
|
1541
|
+
var import_outline4 = require("@heroicons/react/24/outline");
|
|
1542
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1360
1543
|
var ChatMessageList = ({
|
|
1361
1544
|
chatHistory,
|
|
1362
1545
|
isProcessing,
|
|
@@ -1365,10 +1548,10 @@ var ChatMessageList = ({
|
|
|
1365
1548
|
getContextExample,
|
|
1366
1549
|
onInteractiveResponse
|
|
1367
1550
|
}) => {
|
|
1368
|
-
const chatContainerRef = (0,
|
|
1369
|
-
const lastMessageRef = (0,
|
|
1370
|
-
const processingIndicatorRef = (0,
|
|
1371
|
-
(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)(() => {
|
|
1372
1555
|
if (isProcessing && processingIndicatorRef.current) {
|
|
1373
1556
|
processingIndicatorRef.current.scrollIntoView({ behavior: "smooth" });
|
|
1374
1557
|
return;
|
|
@@ -1384,15 +1567,15 @@ var ChatMessageList = ({
|
|
|
1384
1567
|
onInteractiveResponse(messageId, response);
|
|
1385
1568
|
}
|
|
1386
1569
|
};
|
|
1387
|
-
return /* @__PURE__ */ (0,
|
|
1570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1388
1571
|
"div",
|
|
1389
1572
|
{
|
|
1390
1573
|
ref: chatContainerRef,
|
|
1391
1574
|
className: "flex-1 overflow-y-auto p-4 space-y-8 bg-gray-50",
|
|
1392
1575
|
children: [
|
|
1393
|
-
chatHistory.length === 0 && !isProcessing && /* @__PURE__ */ (0,
|
|
1394
|
-
/* @__PURE__ */ (0,
|
|
1395
|
-
/* @__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: [
|
|
1396
1579
|
"Try asking me something like ",
|
|
1397
1580
|
getContextExample()
|
|
1398
1581
|
] })
|
|
@@ -1401,14 +1584,14 @@ var ChatMessageList = ({
|
|
|
1401
1584
|
const isLastMessage = index === chatHistory.length - 1;
|
|
1402
1585
|
const isUser = message.role === "user";
|
|
1403
1586
|
const isError = message.role === "error";
|
|
1404
|
-
return /* @__PURE__ */ (0,
|
|
1587
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1405
1588
|
"div",
|
|
1406
1589
|
{
|
|
1407
1590
|
ref: isLastMessage ? lastMessageRef : void 0,
|
|
1408
1591
|
className: `flex flex-col w-full ${isUser ? "items-end" : "items-start"}`,
|
|
1409
1592
|
children: [
|
|
1410
|
-
/* @__PURE__ */ (0,
|
|
1411
|
-
/* @__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)(
|
|
1412
1595
|
InteractiveMessageHandler_default,
|
|
1413
1596
|
{
|
|
1414
1597
|
message: message.interactiveData,
|
|
@@ -1420,16 +1603,16 @@ var ChatMessageList = ({
|
|
|
1420
1603
|
isResponseSubmitted: !!message.isResponseSubmitted,
|
|
1421
1604
|
parentMessage: message
|
|
1422
1605
|
}
|
|
1423
|
-
) }) : /* @__PURE__ */ (0,
|
|
1606
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1424
1607
|
MessageBubble,
|
|
1425
1608
|
{
|
|
1426
1609
|
message,
|
|
1427
1610
|
isUser
|
|
1428
1611
|
}
|
|
1429
1612
|
) }),
|
|
1430
|
-
isUser && message.interactive && /* @__PURE__ */ (0,
|
|
1431
|
-
/* @__PURE__ */ (0,
|
|
1432
|
-
/* @__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: [
|
|
1433
1616
|
message.request === "form" && "Response to form submission",
|
|
1434
1617
|
message.request === "select" && "Response to selection prompt",
|
|
1435
1618
|
message.request === "confirm" && "Response to confirmation prompt"
|
|
@@ -1440,29 +1623,29 @@ var ChatMessageList = ({
|
|
|
1440
1623
|
message.id || `message-${index}`
|
|
1441
1624
|
);
|
|
1442
1625
|
}),
|
|
1443
|
-
isProcessing && /* @__PURE__ */ (0,
|
|
1626
|
+
isProcessing && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1444
1627
|
"div",
|
|
1445
1628
|
{
|
|
1446
1629
|
ref: processingIndicatorRef,
|
|
1447
1630
|
className: "flex justify-start my-4",
|
|
1448
|
-
children: /* @__PURE__ */ (0,
|
|
1449
|
-
/* @__PURE__ */ (0,
|
|
1450
|
-
/* @__PURE__ */ (0,
|
|
1451
|
-
/* @__PURE__ */ (0,
|
|
1452
|
-
/* @__PURE__ */ (0,
|
|
1453
|
-
/* @__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" } })
|
|
1454
1637
|
] })
|
|
1455
1638
|
] }) })
|
|
1456
1639
|
}
|
|
1457
1640
|
),
|
|
1458
|
-
currentTask && !currentTask.complete && /* @__PURE__ */ (0,
|
|
1459
|
-
/* @__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: [
|
|
1460
1643
|
"Task in progress: Step ",
|
|
1461
1644
|
currentTask.currentStep,
|
|
1462
1645
|
" of ",
|
|
1463
1646
|
currentTask.steps
|
|
1464
1647
|
] }),
|
|
1465
|
-
/* @__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)(
|
|
1466
1649
|
"div",
|
|
1467
1650
|
{
|
|
1468
1651
|
className: "bg-blue-500 h-2 rounded-full",
|
|
@@ -1477,34 +1660,34 @@ var ChatMessageList = ({
|
|
|
1477
1660
|
|
|
1478
1661
|
// src/ui/react/components/ConnectionStatus.tsx
|
|
1479
1662
|
var import_lucide_react2 = require("lucide-react");
|
|
1480
|
-
var
|
|
1663
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1481
1664
|
var ConnectionStatus = ({
|
|
1482
1665
|
connectionStatus,
|
|
1483
1666
|
onReconnect
|
|
1484
1667
|
}) => {
|
|
1485
|
-
return /* @__PURE__ */ (0,
|
|
1486
|
-
/* @__PURE__ */ (0,
|
|
1487
|
-
connectionStatus === "connected" && /* @__PURE__ */ (0,
|
|
1488
|
-
/* @__PURE__ */ (0,
|
|
1489
|
-
/* @__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" })
|
|
1490
1673
|
] }),
|
|
1491
|
-
connectionStatus === "reconnecting" && /* @__PURE__ */ (0,
|
|
1492
|
-
/* @__PURE__ */ (0,
|
|
1493
|
-
/* @__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..." })
|
|
1494
1677
|
] }),
|
|
1495
|
-
connectionStatus === "disconnected" && /* @__PURE__ */ (0,
|
|
1496
|
-
/* @__PURE__ */ (0,
|
|
1497
|
-
/* @__PURE__ */ (0,
|
|
1498
|
-
/* @__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" })
|
|
1499
1682
|
] }),
|
|
1500
|
-
/* @__PURE__ */ (0,
|
|
1683
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1501
1684
|
"button",
|
|
1502
1685
|
{
|
|
1503
1686
|
onClick: onReconnect,
|
|
1504
1687
|
className: "text-blue-600 hover:text-blue-800 flex items-center",
|
|
1505
1688
|
children: [
|
|
1506
|
-
/* @__PURE__ */ (0,
|
|
1507
|
-
/* @__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" })
|
|
1508
1691
|
]
|
|
1509
1692
|
}
|
|
1510
1693
|
)
|
|
@@ -1513,7 +1696,7 @@ var ConnectionStatus = ({
|
|
|
1513
1696
|
};
|
|
1514
1697
|
|
|
1515
1698
|
// src/ui/react/components/Spinner.tsx
|
|
1516
|
-
var
|
|
1699
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1517
1700
|
var Spinner = ({
|
|
1518
1701
|
size = "md",
|
|
1519
1702
|
className = "",
|
|
@@ -1525,7 +1708,7 @@ var Spinner = ({
|
|
|
1525
1708
|
lg: "h-8 w-8",
|
|
1526
1709
|
xl: "h-12 w-12"
|
|
1527
1710
|
};
|
|
1528
|
-
return /* @__PURE__ */ (0,
|
|
1711
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
1529
1712
|
"svg",
|
|
1530
1713
|
{
|
|
1531
1714
|
className: `animate-spin ${sizeClasses[size]} ${color} ${className}`,
|
|
@@ -1533,7 +1716,7 @@ var Spinner = ({
|
|
|
1533
1716
|
fill: "none",
|
|
1534
1717
|
viewBox: "0 0 24 24",
|
|
1535
1718
|
children: [
|
|
1536
|
-
/* @__PURE__ */ (0,
|
|
1719
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1537
1720
|
"circle",
|
|
1538
1721
|
{
|
|
1539
1722
|
className: "opacity-25",
|
|
@@ -1544,7 +1727,7 @@ var Spinner = ({
|
|
|
1544
1727
|
strokeWidth: "4"
|
|
1545
1728
|
}
|
|
1546
1729
|
),
|
|
1547
|
-
/* @__PURE__ */ (0,
|
|
1730
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1548
1731
|
"path",
|
|
1549
1732
|
{
|
|
1550
1733
|
className: "opacity-75",
|