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