@paymanai/payman-ask-sdk 4.0.22 → 4.0.23
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/index.js +347 -262
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +88 -3
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +30 -0
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React = require('react');
|
|
4
4
|
var framerMotion = require('framer-motion');
|
|
5
5
|
var clsx = require('clsx');
|
|
6
6
|
var tailwindMerge = require('tailwind-merge');
|
|
@@ -33,6 +33,7 @@ function _interopNamespace(e) {
|
|
|
33
33
|
return Object.freeze(n);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
36
37
|
var Sentry__namespace = /*#__PURE__*/_interopNamespace(Sentry);
|
|
37
38
|
var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
|
|
38
39
|
var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
|
|
@@ -840,12 +841,12 @@ async function resolveRagImageUrls(config, content, signal) {
|
|
|
840
841
|
}
|
|
841
842
|
var FRIENDLY_ERROR_MESSAGE = "Oops, something went wrong. Please try again.";
|
|
842
843
|
function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForResponse) {
|
|
843
|
-
const abortControllerRef =
|
|
844
|
-
const configRef =
|
|
844
|
+
const abortControllerRef = React.useRef(null);
|
|
845
|
+
const configRef = React.useRef(config);
|
|
845
846
|
configRef.current = config;
|
|
846
|
-
const callbacksRef =
|
|
847
|
+
const callbacksRef = React.useRef(callbacks);
|
|
847
848
|
callbacksRef.current = callbacks;
|
|
848
|
-
const startStream =
|
|
849
|
+
const startStream = React.useCallback(
|
|
849
850
|
async (userMessage, streamingId, sessionId, externalAbortController, options) => {
|
|
850
851
|
abortControllerRef.current?.abort();
|
|
851
852
|
const abortController = externalAbortController ?? new AbortController();
|
|
@@ -1044,7 +1045,7 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
1044
1045
|
},
|
|
1045
1046
|
[setMessages, setIsWaitingForResponse]
|
|
1046
1047
|
);
|
|
1047
|
-
const cancelStream =
|
|
1048
|
+
const cancelStream = React.useCallback(() => {
|
|
1048
1049
|
abortControllerRef.current?.abort();
|
|
1049
1050
|
}, []);
|
|
1050
1051
|
return {
|
|
@@ -1136,24 +1137,24 @@ function getSessionIdFromMessages(messages) {
|
|
|
1136
1137
|
return messages.find((message) => message.sessionId)?.sessionId;
|
|
1137
1138
|
}
|
|
1138
1139
|
function useChatV2(config, callbacks = {}) {
|
|
1139
|
-
const [messages, setMessages] =
|
|
1140
|
-
const [isWaitingForResponse, setIsWaitingForResponse] =
|
|
1140
|
+
const [messages, setMessages] = React.useState(() => getStoredOrInitialMessages(config));
|
|
1141
|
+
const [isWaitingForResponse, setIsWaitingForResponse] = React.useState(() => {
|
|
1141
1142
|
if (!config.userId) return false;
|
|
1142
1143
|
return activeStreamStore.get(config.userId)?.isWaiting ?? false;
|
|
1143
1144
|
});
|
|
1144
|
-
const sessionIdRef =
|
|
1145
|
+
const sessionIdRef = React.useRef(
|
|
1145
1146
|
getSessionIdFromMessages(getStoredOrInitialMessages(config)) ?? config.initialSessionId ?? void 0
|
|
1146
1147
|
);
|
|
1147
|
-
const prevUserIdRef =
|
|
1148
|
-
const streamUserIdRef =
|
|
1149
|
-
const subscriptionPrevUserIdRef =
|
|
1150
|
-
const callbacksRef =
|
|
1148
|
+
const prevUserIdRef = React.useRef(config.userId);
|
|
1149
|
+
const streamUserIdRef = React.useRef(void 0);
|
|
1150
|
+
const subscriptionPrevUserIdRef = React.useRef(config.userId);
|
|
1151
|
+
const callbacksRef = React.useRef(callbacks);
|
|
1151
1152
|
callbacksRef.current = callbacks;
|
|
1152
|
-
const configRef =
|
|
1153
|
+
const configRef = React.useRef(config);
|
|
1153
1154
|
configRef.current = config;
|
|
1154
|
-
const messagesRef =
|
|
1155
|
+
const messagesRef = React.useRef(messages);
|
|
1155
1156
|
messagesRef.current = messages;
|
|
1156
|
-
const storeAwareSetMessages =
|
|
1157
|
+
const storeAwareSetMessages = React.useCallback(
|
|
1157
1158
|
(updater) => {
|
|
1158
1159
|
const streamUserId = streamUserIdRef.current;
|
|
1159
1160
|
const currentUserId = configRef.current.userId;
|
|
@@ -1168,7 +1169,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1168
1169
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1169
1170
|
[]
|
|
1170
1171
|
);
|
|
1171
|
-
const storeAwareSetIsWaiting =
|
|
1172
|
+
const storeAwareSetIsWaiting = React.useCallback(
|
|
1172
1173
|
(waiting) => {
|
|
1173
1174
|
const streamUserId = streamUserIdRef.current;
|
|
1174
1175
|
const currentUserId = configRef.current.userId;
|
|
@@ -1183,8 +1184,8 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1183
1184
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1184
1185
|
[]
|
|
1185
1186
|
);
|
|
1186
|
-
const [userActionState, setUserActionState] =
|
|
1187
|
-
const wrappedCallbacks =
|
|
1187
|
+
const [userActionState, setUserActionState] = React.useState(EMPTY_USER_ACTION_STATE);
|
|
1188
|
+
const wrappedCallbacks = React.useMemo(() => ({
|
|
1188
1189
|
...callbacksRef.current,
|
|
1189
1190
|
onMessageSent: (message) => callbacksRef.current.onMessageSent?.(message),
|
|
1190
1191
|
onStreamStart: () => callbacksRef.current.onStreamStart?.(),
|
|
@@ -1213,7 +1214,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1213
1214
|
storeAwareSetMessages,
|
|
1214
1215
|
storeAwareSetIsWaiting
|
|
1215
1216
|
);
|
|
1216
|
-
const sendMessage =
|
|
1217
|
+
const sendMessage = React.useCallback(
|
|
1217
1218
|
async (userMessage, options) => {
|
|
1218
1219
|
if (!userMessage.trim()) return;
|
|
1219
1220
|
if (!sessionIdRef.current && configRef.current.autoGenerateSessionId !== false) {
|
|
@@ -1273,16 +1274,16 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1273
1274
|
},
|
|
1274
1275
|
[startStream]
|
|
1275
1276
|
);
|
|
1276
|
-
const clearMessages =
|
|
1277
|
+
const clearMessages = React.useCallback(() => {
|
|
1277
1278
|
if (configRef.current.userId) {
|
|
1278
1279
|
chatStore.delete(configRef.current.userId);
|
|
1279
1280
|
}
|
|
1280
1281
|
setMessages([]);
|
|
1281
1282
|
}, []);
|
|
1282
|
-
const prependMessages =
|
|
1283
|
+
const prependMessages = React.useCallback((msgs) => {
|
|
1283
1284
|
setMessages((prev) => [...msgs, ...prev]);
|
|
1284
1285
|
}, []);
|
|
1285
|
-
const cancelStream =
|
|
1286
|
+
const cancelStream = React.useCallback(() => {
|
|
1286
1287
|
const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
|
|
1287
1288
|
if (streamUserId) {
|
|
1288
1289
|
activeStreamStore.abort(streamUserId);
|
|
@@ -1306,7 +1307,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1306
1307
|
})
|
|
1307
1308
|
);
|
|
1308
1309
|
}, [cancelStreamManager]);
|
|
1309
|
-
const resetSession =
|
|
1310
|
+
const resetSession = React.useCallback(() => {
|
|
1310
1311
|
const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
|
|
1311
1312
|
if (streamUserId) {
|
|
1312
1313
|
activeStreamStore.abort(streamUserId);
|
|
@@ -1321,13 +1322,13 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1321
1322
|
setIsWaitingForResponse(false);
|
|
1322
1323
|
setUserActionState(EMPTY_USER_ACTION_STATE);
|
|
1323
1324
|
}, []);
|
|
1324
|
-
const getSessionId =
|
|
1325
|
+
const getSessionId = React.useCallback(() => {
|
|
1325
1326
|
return sessionIdRef.current;
|
|
1326
1327
|
}, []);
|
|
1327
|
-
const getMessages =
|
|
1328
|
+
const getMessages = React.useCallback(() => {
|
|
1328
1329
|
return messages;
|
|
1329
1330
|
}, [messages]);
|
|
1330
|
-
const setPromptStatus =
|
|
1331
|
+
const setPromptStatus = React.useCallback(
|
|
1331
1332
|
(userActionId, status) => {
|
|
1332
1333
|
setUserActionState((prev) => ({
|
|
1333
1334
|
...prev,
|
|
@@ -1338,13 +1339,13 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1338
1339
|
},
|
|
1339
1340
|
[]
|
|
1340
1341
|
);
|
|
1341
|
-
const removePrompt =
|
|
1342
|
+
const removePrompt = React.useCallback((userActionId) => {
|
|
1342
1343
|
setUserActionState((prev) => ({
|
|
1343
1344
|
...prev,
|
|
1344
1345
|
prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
|
|
1345
1346
|
}));
|
|
1346
1347
|
}, []);
|
|
1347
|
-
const submitUserAction2 =
|
|
1348
|
+
const submitUserAction2 = React.useCallback(
|
|
1348
1349
|
async (userActionId, content) => {
|
|
1349
1350
|
setPromptStatus(userActionId, "submitting");
|
|
1350
1351
|
try {
|
|
@@ -1362,7 +1363,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1362
1363
|
},
|
|
1363
1364
|
[removePrompt, setPromptStatus]
|
|
1364
1365
|
);
|
|
1365
|
-
const cancelUserAction2 =
|
|
1366
|
+
const cancelUserAction2 = React.useCallback(
|
|
1366
1367
|
async (userActionId) => {
|
|
1367
1368
|
setPromptStatus(userActionId, "submitting");
|
|
1368
1369
|
try {
|
|
@@ -1380,7 +1381,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1380
1381
|
},
|
|
1381
1382
|
[removePrompt, setPromptStatus]
|
|
1382
1383
|
);
|
|
1383
|
-
const resendUserAction2 =
|
|
1384
|
+
const resendUserAction2 = React.useCallback(
|
|
1384
1385
|
async (userActionId) => {
|
|
1385
1386
|
setPromptStatus(userActionId, "submitting");
|
|
1386
1387
|
try {
|
|
@@ -1398,7 +1399,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1398
1399
|
},
|
|
1399
1400
|
[setPromptStatus]
|
|
1400
1401
|
);
|
|
1401
|
-
const expireUserAction2 =
|
|
1402
|
+
const expireUserAction2 = React.useCallback(
|
|
1402
1403
|
async (userActionId) => {
|
|
1403
1404
|
setPromptStatus(userActionId, "expired");
|
|
1404
1405
|
try {
|
|
@@ -1411,13 +1412,13 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1411
1412
|
},
|
|
1412
1413
|
[setPromptStatus]
|
|
1413
1414
|
);
|
|
1414
|
-
const dismissNotification =
|
|
1415
|
+
const dismissNotification = React.useCallback((id) => {
|
|
1415
1416
|
setUserActionState((prev) => ({
|
|
1416
1417
|
...prev,
|
|
1417
1418
|
notifications: prev.notifications.filter((n) => n.id !== id)
|
|
1418
1419
|
}));
|
|
1419
1420
|
}, []);
|
|
1420
|
-
|
|
1421
|
+
React.useEffect(() => {
|
|
1421
1422
|
const prevSubscriptionUserId = subscriptionPrevUserIdRef.current;
|
|
1422
1423
|
subscriptionPrevUserIdRef.current = config.userId;
|
|
1423
1424
|
const { userId } = config;
|
|
@@ -1436,7 +1437,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1436
1437
|
}
|
|
1437
1438
|
return unsubscribe;
|
|
1438
1439
|
}, [config.userId]);
|
|
1439
|
-
|
|
1440
|
+
React.useEffect(() => {
|
|
1440
1441
|
if (!config.userId) return;
|
|
1441
1442
|
if (prevUserIdRef.current !== config.userId) return;
|
|
1442
1443
|
const toSave = messages.filter((m) => !m.isStreaming);
|
|
@@ -1444,14 +1445,14 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1444
1445
|
chatStore.set(config.userId, toSave);
|
|
1445
1446
|
}
|
|
1446
1447
|
}, [messages, config.userId]);
|
|
1447
|
-
|
|
1448
|
+
React.useEffect(() => {
|
|
1448
1449
|
if (!config.userId || activeStreamStore.has(config.userId)) return;
|
|
1449
1450
|
if (!config.initialMessages?.length || messagesRef.current.length > 0) return;
|
|
1450
1451
|
chatStore.set(config.userId, config.initialMessages);
|
|
1451
1452
|
setMessages(config.initialMessages);
|
|
1452
1453
|
sessionIdRef.current = getSessionIdFromMessages(config.initialMessages) ?? config.initialSessionId;
|
|
1453
1454
|
}, [config.initialMessages, config.initialSessionId, config.userId]);
|
|
1454
|
-
|
|
1455
|
+
React.useEffect(() => {
|
|
1455
1456
|
const prevUserId = prevUserIdRef.current;
|
|
1456
1457
|
prevUserIdRef.current = config.userId;
|
|
1457
1458
|
if (prevUserId === config.userId) return;
|
|
@@ -1499,12 +1500,12 @@ function getSpeechRecognition() {
|
|
|
1499
1500
|
return window.SpeechRecognition || window.webkitSpeechRecognition || null;
|
|
1500
1501
|
}
|
|
1501
1502
|
function useVoice(config = {}, callbacks = {}) {
|
|
1502
|
-
const [voiceState, setVoiceState] =
|
|
1503
|
-
const [transcribedText, setTranscribedText] =
|
|
1504
|
-
const [isAvailable, setIsAvailable] =
|
|
1505
|
-
const [isRecording, setIsRecording] =
|
|
1506
|
-
const recognitionRef =
|
|
1507
|
-
const autoStopTimerRef =
|
|
1503
|
+
const [voiceState, setVoiceState] = React.useState("idle");
|
|
1504
|
+
const [transcribedText, setTranscribedText] = React.useState("");
|
|
1505
|
+
const [isAvailable, setIsAvailable] = React.useState(false);
|
|
1506
|
+
const [isRecording, setIsRecording] = React.useState(false);
|
|
1507
|
+
const recognitionRef = React.useRef(null);
|
|
1508
|
+
const autoStopTimerRef = React.useRef(null);
|
|
1508
1509
|
const {
|
|
1509
1510
|
lang = "en-US",
|
|
1510
1511
|
interimResults = true,
|
|
@@ -1513,14 +1514,14 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1513
1514
|
autoStopAfterSilence
|
|
1514
1515
|
} = config;
|
|
1515
1516
|
const { onStart, onEnd, onResult, onError, onStateChange } = callbacks;
|
|
1516
|
-
|
|
1517
|
+
React.useEffect(() => {
|
|
1517
1518
|
const SpeechRecognitionAPI = getSpeechRecognition();
|
|
1518
1519
|
setIsAvailable(SpeechRecognitionAPI !== null);
|
|
1519
1520
|
}, []);
|
|
1520
|
-
|
|
1521
|
+
React.useEffect(() => {
|
|
1521
1522
|
onStateChange?.(voiceState);
|
|
1522
1523
|
}, [voiceState, onStateChange]);
|
|
1523
|
-
const requestPermissions =
|
|
1524
|
+
const requestPermissions = React.useCallback(async () => {
|
|
1524
1525
|
try {
|
|
1525
1526
|
const result = await navigator.mediaDevices.getUserMedia({
|
|
1526
1527
|
audio: true
|
|
@@ -1537,7 +1538,7 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1537
1538
|
};
|
|
1538
1539
|
}
|
|
1539
1540
|
}, []);
|
|
1540
|
-
const getPermissions =
|
|
1541
|
+
const getPermissions = React.useCallback(async () => {
|
|
1541
1542
|
if (typeof navigator === "undefined" || !navigator.permissions) {
|
|
1542
1543
|
return {
|
|
1543
1544
|
granted: false,
|
|
@@ -1559,13 +1560,13 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1559
1560
|
};
|
|
1560
1561
|
}
|
|
1561
1562
|
}, []);
|
|
1562
|
-
const clearAutoStopTimer =
|
|
1563
|
+
const clearAutoStopTimer = React.useCallback(() => {
|
|
1563
1564
|
if (autoStopTimerRef.current) {
|
|
1564
1565
|
clearTimeout(autoStopTimerRef.current);
|
|
1565
1566
|
autoStopTimerRef.current = null;
|
|
1566
1567
|
}
|
|
1567
1568
|
}, []);
|
|
1568
|
-
const resetAutoStopTimer =
|
|
1569
|
+
const resetAutoStopTimer = React.useCallback(() => {
|
|
1569
1570
|
clearAutoStopTimer();
|
|
1570
1571
|
if (autoStopAfterSilence && autoStopAfterSilence > 0) {
|
|
1571
1572
|
autoStopTimerRef.current = setTimeout(() => {
|
|
@@ -1575,7 +1576,7 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1575
1576
|
}, autoStopAfterSilence);
|
|
1576
1577
|
}
|
|
1577
1578
|
}, [autoStopAfterSilence, clearAutoStopTimer, isRecording]);
|
|
1578
|
-
const stopRecording =
|
|
1579
|
+
const stopRecording = React.useCallback(() => {
|
|
1579
1580
|
if (recognitionRef.current) {
|
|
1580
1581
|
try {
|
|
1581
1582
|
recognitionRef.current.stop();
|
|
@@ -1587,7 +1588,7 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1587
1588
|
setIsRecording(false);
|
|
1588
1589
|
setVoiceState("idle");
|
|
1589
1590
|
}, [clearAutoStopTimer]);
|
|
1590
|
-
const startRecording =
|
|
1591
|
+
const startRecording = React.useCallback(async () => {
|
|
1591
1592
|
const SpeechRecognitionAPI = getSpeechRecognition();
|
|
1592
1593
|
if (!SpeechRecognitionAPI) {
|
|
1593
1594
|
onError?.("Speech recognition not supported in this browser");
|
|
@@ -1677,15 +1678,15 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1677
1678
|
resetAutoStopTimer,
|
|
1678
1679
|
clearAutoStopTimer
|
|
1679
1680
|
]);
|
|
1680
|
-
const clearTranscript =
|
|
1681
|
+
const clearTranscript = React.useCallback(() => {
|
|
1681
1682
|
setTranscribedText("");
|
|
1682
1683
|
}, []);
|
|
1683
|
-
const reset =
|
|
1684
|
+
const reset = React.useCallback(() => {
|
|
1684
1685
|
stopRecording();
|
|
1685
1686
|
setTranscribedText("");
|
|
1686
1687
|
setVoiceState("idle");
|
|
1687
1688
|
}, [stopRecording]);
|
|
1688
|
-
|
|
1689
|
+
React.useEffect(() => {
|
|
1689
1690
|
return () => {
|
|
1690
1691
|
if (recognitionRef.current) {
|
|
1691
1692
|
try {
|
|
@@ -1825,9 +1826,9 @@ function buildContent(schema, values) {
|
|
|
1825
1826
|
}
|
|
1826
1827
|
return content;
|
|
1827
1828
|
}
|
|
1828
|
-
var PaymanChatContext =
|
|
1829
|
+
var PaymanChatContext = React.createContext(void 0);
|
|
1829
1830
|
function usePaymanChat() {
|
|
1830
|
-
const context =
|
|
1831
|
+
const context = React.useContext(PaymanChatContext);
|
|
1831
1832
|
if (!context) {
|
|
1832
1833
|
throw new Error("usePaymanChat must be used within a PaymanChat component");
|
|
1833
1834
|
}
|
|
@@ -2085,8 +2086,8 @@ function ImageLightbox({
|
|
|
2085
2086
|
alt = "",
|
|
2086
2087
|
onClose
|
|
2087
2088
|
}) {
|
|
2088
|
-
const [isMounted, setIsMounted] =
|
|
2089
|
-
const [isImageLoaded, setIsImageLoaded] =
|
|
2089
|
+
const [isMounted, setIsMounted] = React.useState(false);
|
|
2090
|
+
const [isImageLoaded, setIsImageLoaded] = React.useState(false);
|
|
2090
2091
|
const overlayStyle = {
|
|
2091
2092
|
position: "fixed",
|
|
2092
2093
|
inset: 0,
|
|
@@ -2107,14 +2108,14 @@ function ImageLightbox({
|
|
|
2107
2108
|
justifyContent: "center",
|
|
2108
2109
|
overflow: "hidden"
|
|
2109
2110
|
};
|
|
2110
|
-
|
|
2111
|
+
React.useEffect(() => {
|
|
2111
2112
|
setIsMounted(true);
|
|
2112
2113
|
return () => setIsMounted(false);
|
|
2113
2114
|
}, []);
|
|
2114
|
-
|
|
2115
|
+
React.useEffect(() => {
|
|
2115
2116
|
setIsImageLoaded(false);
|
|
2116
2117
|
}, [src]);
|
|
2117
|
-
|
|
2118
|
+
React.useEffect(() => {
|
|
2118
2119
|
if (typeof document === "undefined") return;
|
|
2119
2120
|
const previousOverflow = document.body.style.overflow;
|
|
2120
2121
|
document.body.style.overflow = "hidden";
|
|
@@ -2122,7 +2123,7 @@ function ImageLightbox({
|
|
|
2122
2123
|
document.body.style.overflow = previousOverflow;
|
|
2123
2124
|
};
|
|
2124
2125
|
}, []);
|
|
2125
|
-
|
|
2126
|
+
React.useEffect(() => {
|
|
2126
2127
|
if (typeof document === "undefined") return;
|
|
2127
2128
|
const handleKeyDown = (event) => {
|
|
2128
2129
|
if (event.key === "Escape") {
|
|
@@ -2218,15 +2219,15 @@ function MarkdownImage({
|
|
|
2218
2219
|
maxHeight: "18rem",
|
|
2219
2220
|
objectFit: "contain"
|
|
2220
2221
|
};
|
|
2221
|
-
const [isLoaded, setIsLoaded] =
|
|
2222
|
-
const [hasError, setHasError] =
|
|
2223
|
-
const [isLightboxOpen, setIsLightboxOpen] =
|
|
2224
|
-
const isUnresolvedRagImage =
|
|
2222
|
+
const [isLoaded, setIsLoaded] = React.useState(false);
|
|
2223
|
+
const [hasError, setHasError] = React.useState(false);
|
|
2224
|
+
const [isLightboxOpen, setIsLightboxOpen] = React.useState(false);
|
|
2225
|
+
const isUnresolvedRagImage = React.useMemo(
|
|
2225
2226
|
() => src ? isUnresolvedRagImageSource(src) : false,
|
|
2226
2227
|
[src]
|
|
2227
2228
|
);
|
|
2228
2229
|
const isResolvingRagImage = isResolving && isUnresolvedRagImage;
|
|
2229
|
-
|
|
2230
|
+
React.useEffect(() => {
|
|
2230
2231
|
setIsLoaded(false);
|
|
2231
2232
|
setHasError(false);
|
|
2232
2233
|
setIsLightboxOpen(false);
|
|
@@ -2353,9 +2354,9 @@ function AgentMessage({
|
|
|
2353
2354
|
const hasTraceData = !!(message.tracingData || message.executionId) && !isStreaming;
|
|
2354
2355
|
const isCancelled = message.isCancelled ?? false;
|
|
2355
2356
|
const currentExecutingStepId = message.currentExecutingStepId;
|
|
2356
|
-
const [isStepsExpanded, setIsStepsExpanded] =
|
|
2357
|
-
const wasStreamingRef =
|
|
2358
|
-
|
|
2357
|
+
const [isStepsExpanded, setIsStepsExpanded] = React.useState(false);
|
|
2358
|
+
const wasStreamingRef = React.useRef(isStreaming);
|
|
2359
|
+
React.useEffect(() => {
|
|
2359
2360
|
if (isStreaming && hasSteps) {
|
|
2360
2361
|
setIsStepsExpanded(true);
|
|
2361
2362
|
}
|
|
@@ -2372,13 +2373,13 @@ function AgentMessage({
|
|
|
2372
2373
|
const completedWithNoContent = !isStreaming && !isCancelled && content.length === 0 && (message.streamProgress === "completed" || message.streamProgress === "error");
|
|
2373
2374
|
const conflictErrorMessage = getConflictErrorMessage(message.errorDetails);
|
|
2374
2375
|
const isError = !!conflictErrorMessage || (isFriendlyWorkflowError(message.errorDetails) || looksLikeRawError(content)) && !hasMeaningfulContent || completedWithNoContent;
|
|
2375
|
-
const currentStep =
|
|
2376
|
+
const currentStep = React.useMemo(
|
|
2376
2377
|
() => message.steps?.find(
|
|
2377
2378
|
(s) => s.id === currentExecutingStepId && s.status === "in_progress"
|
|
2378
2379
|
),
|
|
2379
2380
|
[message.steps, currentExecutingStepId]
|
|
2380
2381
|
);
|
|
2381
|
-
const markdownRenderers =
|
|
2382
|
+
const markdownRenderers = React.useMemo(
|
|
2382
2383
|
() => createMarkdownComponents({
|
|
2383
2384
|
isResolvingImages: message.isResolvingImages
|
|
2384
2385
|
}),
|
|
@@ -2452,8 +2453,8 @@ function AgentMessage({
|
|
|
2452
2453
|
}) })
|
|
2453
2454
|
}
|
|
2454
2455
|
) });
|
|
2455
|
-
const stepsToggleRef =
|
|
2456
|
-
const handleStepsToggle =
|
|
2456
|
+
const stepsToggleRef = React.useRef(null);
|
|
2457
|
+
const handleStepsToggle = React.useCallback(() => {
|
|
2457
2458
|
setIsStepsExpanded((prev) => {
|
|
2458
2459
|
const next = !prev;
|
|
2459
2460
|
if (next) {
|
|
@@ -2781,23 +2782,23 @@ function MessageList({
|
|
|
2781
2782
|
isLoadingMoreMessages = false,
|
|
2782
2783
|
hasMoreMessages = false
|
|
2783
2784
|
}) {
|
|
2784
|
-
const scrollRef =
|
|
2785
|
-
const isNearBottomRef =
|
|
2786
|
-
const [showScrollBtn, setShowScrollBtn] =
|
|
2787
|
-
const prevMessageCountRef =
|
|
2788
|
-
const scrollHeightBeforePrependRef =
|
|
2789
|
-
const firstMessageIdRef =
|
|
2790
|
-
const getDistanceFromBottom =
|
|
2785
|
+
const scrollRef = React.useRef(null);
|
|
2786
|
+
const isNearBottomRef = React.useRef(true);
|
|
2787
|
+
const [showScrollBtn, setShowScrollBtn] = React.useState(false);
|
|
2788
|
+
const prevMessageCountRef = React.useRef(messages.length);
|
|
2789
|
+
const scrollHeightBeforePrependRef = React.useRef(null);
|
|
2790
|
+
const firstMessageIdRef = React.useRef(messages[0]?.id);
|
|
2791
|
+
const getDistanceFromBottom = React.useCallback(() => {
|
|
2791
2792
|
const el = scrollRef.current;
|
|
2792
2793
|
if (!el) return 0;
|
|
2793
2794
|
return el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
2794
2795
|
}, []);
|
|
2795
|
-
const scrollToBottom =
|
|
2796
|
+
const scrollToBottom = React.useCallback((behavior = "smooth") => {
|
|
2796
2797
|
const el = scrollRef.current;
|
|
2797
2798
|
if (!el) return;
|
|
2798
2799
|
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
2799
2800
|
}, []);
|
|
2800
|
-
const handleScroll =
|
|
2801
|
+
const handleScroll = React.useCallback(() => {
|
|
2801
2802
|
const el = scrollRef.current;
|
|
2802
2803
|
if (!el) return;
|
|
2803
2804
|
const distance = getDistanceFromBottom();
|
|
@@ -2809,7 +2810,7 @@ function MessageList({
|
|
|
2809
2810
|
onLoadMoreMessages();
|
|
2810
2811
|
}
|
|
2811
2812
|
}, [getDistanceFromBottom, hasMoreMessages, isLoadingMoreMessages, onLoadMoreMessages]);
|
|
2812
|
-
|
|
2813
|
+
React.useLayoutEffect(() => {
|
|
2813
2814
|
const el = scrollRef.current;
|
|
2814
2815
|
const prevHeight = scrollHeightBeforePrependRef.current;
|
|
2815
2816
|
const newFirstId = messages[0]?.id;
|
|
@@ -2819,25 +2820,25 @@ function MessageList({
|
|
|
2819
2820
|
}
|
|
2820
2821
|
firstMessageIdRef.current = newFirstId;
|
|
2821
2822
|
}, [messages]);
|
|
2822
|
-
|
|
2823
|
+
React.useEffect(() => {
|
|
2823
2824
|
const prevCount = prevMessageCountRef.current;
|
|
2824
2825
|
prevMessageCountRef.current = messages.length;
|
|
2825
2826
|
if (messages.length > prevCount && isNearBottomRef.current) {
|
|
2826
2827
|
requestAnimationFrame(() => scrollToBottom());
|
|
2827
2828
|
}
|
|
2828
2829
|
}, [messages.length, scrollToBottom]);
|
|
2829
|
-
|
|
2830
|
+
React.useEffect(() => {
|
|
2830
2831
|
const lastMsg = messages[messages.length - 1];
|
|
2831
2832
|
if (!lastMsg?.isStreaming) return;
|
|
2832
2833
|
if (!isNearBottomRef.current) return;
|
|
2833
2834
|
requestAnimationFrame(() => scrollToBottom());
|
|
2834
2835
|
});
|
|
2835
|
-
|
|
2836
|
+
React.useEffect(() => {
|
|
2836
2837
|
if (messages.length > 0) {
|
|
2837
2838
|
setTimeout(() => scrollToBottom("instant"), 50);
|
|
2838
2839
|
}
|
|
2839
2840
|
}, []);
|
|
2840
|
-
|
|
2841
|
+
React.useEffect(() => {
|
|
2841
2842
|
const handleStepsToggle = () => {
|
|
2842
2843
|
requestAnimationFrame(() => {
|
|
2843
2844
|
requestAnimationFrame(() => {
|
|
@@ -2854,7 +2855,7 @@ function MessageList({
|
|
|
2854
2855
|
return () => el.removeEventListener("payman-steps-toggle", handleStepsToggle);
|
|
2855
2856
|
}
|
|
2856
2857
|
}, [getDistanceFromBottom, scrollToBottom]);
|
|
2857
|
-
const handleScrollToBottom =
|
|
2858
|
+
const handleScrollToBottom = React.useCallback(() => {
|
|
2858
2859
|
scrollToBottom();
|
|
2859
2860
|
}, [scrollToBottom]);
|
|
2860
2861
|
if (isLoading) {
|
|
@@ -2987,7 +2988,7 @@ function ResetSessionConfirmModal({
|
|
|
2987
2988
|
onClose,
|
|
2988
2989
|
onConfirm
|
|
2989
2990
|
}) {
|
|
2990
|
-
const handleKeyDown =
|
|
2991
|
+
const handleKeyDown = React.useCallback(
|
|
2991
2992
|
(event) => {
|
|
2992
2993
|
if (event.key === "Escape") {
|
|
2993
2994
|
onClose();
|
|
@@ -2995,7 +2996,7 @@ function ResetSessionConfirmModal({
|
|
|
2995
2996
|
},
|
|
2996
2997
|
[onClose]
|
|
2997
2998
|
);
|
|
2998
|
-
|
|
2999
|
+
React.useEffect(() => {
|
|
2999
3000
|
if (!isOpen || typeof document === "undefined") return;
|
|
3000
3001
|
document.addEventListener("keydown", handleKeyDown);
|
|
3001
3002
|
const previousOverflow = document.body.style.overflow;
|
|
@@ -3101,14 +3102,14 @@ function UserMessageV2({
|
|
|
3101
3102
|
retryDisabled = false,
|
|
3102
3103
|
actions
|
|
3103
3104
|
}) {
|
|
3104
|
-
const [copied, setCopied] =
|
|
3105
|
-
const [toast, setToast] =
|
|
3106
|
-
const copyResetTimerRef =
|
|
3107
|
-
const toastTimerRef =
|
|
3105
|
+
const [copied, setCopied] = React.useState(false);
|
|
3106
|
+
const [toast, setToast] = React.useState(null);
|
|
3107
|
+
const copyResetTimerRef = React.useRef(null);
|
|
3108
|
+
const toastTimerRef = React.useRef(null);
|
|
3108
3109
|
const showCopyAction = actions?.copy ?? true;
|
|
3109
3110
|
const showEditAction = actions?.edit ?? false;
|
|
3110
3111
|
const showRetryAction = actions?.retry ?? false;
|
|
3111
|
-
|
|
3112
|
+
React.useEffect(() => {
|
|
3112
3113
|
return () => {
|
|
3113
3114
|
if (copyResetTimerRef.current) clearTimeout(copyResetTimerRef.current);
|
|
3114
3115
|
if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
|
|
@@ -3264,18 +3265,18 @@ function MarkdownImageV2({
|
|
|
3264
3265
|
onImageClick
|
|
3265
3266
|
}) {
|
|
3266
3267
|
const cachedAlready = src ? loadedImageCache.has(src) : false;
|
|
3267
|
-
const [isVisible, setIsVisible] =
|
|
3268
|
-
const [isLoaded, setIsLoaded] =
|
|
3269
|
-
const [hasError, setHasError] =
|
|
3270
|
-
const [retryCount, setRetryCount] =
|
|
3271
|
-
const sentinelRef =
|
|
3272
|
-
const prevLoadedRef =
|
|
3273
|
-
const isUnresolvedRag =
|
|
3268
|
+
const [isVisible, setIsVisible] = React.useState(cachedAlready);
|
|
3269
|
+
const [isLoaded, setIsLoaded] = React.useState(cachedAlready);
|
|
3270
|
+
const [hasError, setHasError] = React.useState(false);
|
|
3271
|
+
const [retryCount, setRetryCount] = React.useState(0);
|
|
3272
|
+
const sentinelRef = React.useRef(null);
|
|
3273
|
+
const prevLoadedRef = React.useRef(cachedAlready);
|
|
3274
|
+
const isUnresolvedRag = React.useMemo(
|
|
3274
3275
|
() => src ? isUnresolvedRagImageSource2(src) : false,
|
|
3275
3276
|
[src]
|
|
3276
3277
|
);
|
|
3277
3278
|
const isResolvingRag = Boolean(isResolving && isUnresolvedRag);
|
|
3278
|
-
|
|
3279
|
+
React.useEffect(() => {
|
|
3279
3280
|
if (src && loadedImageCache.has(src)) {
|
|
3280
3281
|
setIsLoaded(true);
|
|
3281
3282
|
setIsVisible(true);
|
|
@@ -3284,7 +3285,7 @@ function MarkdownImageV2({
|
|
|
3284
3285
|
setHasError(false);
|
|
3285
3286
|
setRetryCount(0);
|
|
3286
3287
|
}, [src]);
|
|
3287
|
-
|
|
3288
|
+
React.useEffect(() => {
|
|
3288
3289
|
const el = sentinelRef.current;
|
|
3289
3290
|
if (!el || !src) return;
|
|
3290
3291
|
const rect = el.getBoundingClientRect();
|
|
@@ -3405,9 +3406,88 @@ function MarkdownImageV2({
|
|
|
3405
3406
|
}
|
|
3406
3407
|
) });
|
|
3407
3408
|
}
|
|
3408
|
-
|
|
3409
|
+
var RAG_SOURCE_CLASS = "payman-v2-rag-source";
|
|
3410
|
+
var RAG_FOLLOW_UP_CLASS = "payman-v2-rag-follow-up";
|
|
3411
|
+
var SOURCE_PATTERN = /^Sources?:\s*\S/i;
|
|
3412
|
+
var MAX_FOLLOW_UP_LENGTH = 320;
|
|
3413
|
+
var HR_PATTERN = /^-{3,}$|^_{3,}$|^\*{3,}$/;
|
|
3414
|
+
function normalizeRagParagraphText(text) {
|
|
3415
|
+
return text.replace(/\s+/g, " ").trim();
|
|
3416
|
+
}
|
|
3417
|
+
function isRagSourceParagraph(text) {
|
|
3418
|
+
return SOURCE_PATTERN.test(normalizeRagParagraphText(text));
|
|
3419
|
+
}
|
|
3420
|
+
function isRagFollowUpCandidate(text) {
|
|
3421
|
+
const normalized = normalizeRagParagraphText(text);
|
|
3422
|
+
return normalized.length > 0 && normalized.length <= MAX_FOLLOW_UP_LENGTH && normalized.endsWith("?");
|
|
3423
|
+
}
|
|
3424
|
+
function extractRagParagraphTexts(content) {
|
|
3425
|
+
const paragraphs = [];
|
|
3426
|
+
const currentParagraph = [];
|
|
3427
|
+
const flushParagraph = () => {
|
|
3428
|
+
const paragraph = normalizeRagParagraphText(currentParagraph.join(" "));
|
|
3429
|
+
currentParagraph.length = 0;
|
|
3430
|
+
if (paragraph) paragraphs.push(paragraph);
|
|
3431
|
+
};
|
|
3432
|
+
content.replace(/\\n/g, "\n").split(/\r?\n/).forEach((line) => {
|
|
3433
|
+
const trimmedLine = line.trim();
|
|
3434
|
+
if (!trimmedLine) {
|
|
3435
|
+
flushParagraph();
|
|
3436
|
+
return;
|
|
3437
|
+
}
|
|
3438
|
+
if (HR_PATTERN.test(trimmedLine)) {
|
|
3439
|
+
flushParagraph();
|
|
3440
|
+
return;
|
|
3441
|
+
}
|
|
3442
|
+
currentParagraph.push(trimmedLine);
|
|
3443
|
+
});
|
|
3444
|
+
flushParagraph();
|
|
3445
|
+
return paragraphs;
|
|
3446
|
+
}
|
|
3447
|
+
function getRagAnswerParagraphRoles(paragraphs) {
|
|
3448
|
+
const normalized = paragraphs.map(normalizeRagParagraphText);
|
|
3449
|
+
const roles = normalized.map(() => null);
|
|
3450
|
+
const sourceIndexes = normalized.map((paragraph, index) => isRagSourceParagraph(paragraph) ? index : -1).filter((index) => index >= 0);
|
|
3451
|
+
for (const sourceIndex of sourceIndexes) {
|
|
3452
|
+
roles[sourceIndex] = "source";
|
|
3453
|
+
for (const candidateIndex of [sourceIndex - 1, sourceIndex + 1]) {
|
|
3454
|
+
if (candidateIndex >= 0 && candidateIndex < normalized.length && roles[candidateIndex] == null && isRagFollowUpCandidate(normalized[candidateIndex] ?? "")) {
|
|
3455
|
+
roles[candidateIndex] = "follow-up";
|
|
3456
|
+
}
|
|
3457
|
+
}
|
|
3458
|
+
}
|
|
3459
|
+
return roles;
|
|
3460
|
+
}
|
|
3461
|
+
function getRagAnswerParagraphRole(paragraph, paragraphs) {
|
|
3462
|
+
const normalizedParagraph = normalizeRagParagraphText(paragraph);
|
|
3463
|
+
if (isRagSourceParagraph(normalizedParagraph)) return "source";
|
|
3464
|
+
const roles = getRagAnswerParagraphRoles(paragraphs);
|
|
3465
|
+
return paragraphs.map(normalizeRagParagraphText).some((candidate, index) => {
|
|
3466
|
+
return candidate === normalizedParagraph && roles[index] === "follow-up";
|
|
3467
|
+
}) ? "follow-up" : null;
|
|
3468
|
+
}
|
|
3469
|
+
function ragAnswerRoleClassName(role) {
|
|
3470
|
+
if (role === "source") return RAG_SOURCE_CLASS;
|
|
3471
|
+
if (role === "follow-up") return RAG_FOLLOW_UP_CLASS;
|
|
3472
|
+
return void 0;
|
|
3473
|
+
}
|
|
3474
|
+
function reactNodeText(node) {
|
|
3475
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
3476
|
+
if (Array.isArray(node)) return node.map(reactNodeText).join("");
|
|
3477
|
+
if (React__namespace.isValidElement(node)) {
|
|
3478
|
+
return reactNodeText(node.props.children);
|
|
3479
|
+
}
|
|
3480
|
+
return "";
|
|
3481
|
+
}
|
|
3482
|
+
function buildComponents(onImageClick, isResolvingRef, ragParagraphsRef) {
|
|
3409
3483
|
return {
|
|
3410
|
-
p: ({ children }) =>
|
|
3484
|
+
p: ({ children }) => {
|
|
3485
|
+
const role = getRagAnswerParagraphRole(
|
|
3486
|
+
reactNodeText(children),
|
|
3487
|
+
ragParagraphsRef?.current ?? []
|
|
3488
|
+
);
|
|
3489
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: ragAnswerRoleClassName(role), children });
|
|
3490
|
+
},
|
|
3411
3491
|
code: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("code", { children }),
|
|
3412
3492
|
pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-markdown-pre", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { children }) }),
|
|
3413
3493
|
ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { children }),
|
|
@@ -3443,10 +3523,15 @@ function MarkdownRendererV2({
|
|
|
3443
3523
|
isResolvingImages,
|
|
3444
3524
|
onImageClick
|
|
3445
3525
|
}) {
|
|
3446
|
-
const isResolvingRef =
|
|
3526
|
+
const isResolvingRef = React.useRef(isResolvingImages);
|
|
3447
3527
|
isResolvingRef.current = isResolvingImages;
|
|
3448
|
-
const
|
|
3449
|
-
|
|
3528
|
+
const ragParagraphsRef = React.useRef([]);
|
|
3529
|
+
ragParagraphsRef.current = React.useMemo(
|
|
3530
|
+
() => extractRagParagraphTexts(content),
|
|
3531
|
+
[content]
|
|
3532
|
+
);
|
|
3533
|
+
const components = React.useMemo(
|
|
3534
|
+
() => buildComponents(onImageClick, isResolvingRef, ragParagraphsRef),
|
|
3450
3535
|
[onImageClick]
|
|
3451
3536
|
);
|
|
3452
3537
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3503,14 +3588,14 @@ function FeedbackReasonModal({
|
|
|
3503
3588
|
onClose,
|
|
3504
3589
|
onSubmit
|
|
3505
3590
|
}) {
|
|
3506
|
-
const [reason, setReason] =
|
|
3591
|
+
const [reason, setReason] = React.useState(
|
|
3507
3592
|
NEGATIVE_FEEDBACK_REASONS[0].value
|
|
3508
3593
|
);
|
|
3509
|
-
const [details, setDetails] =
|
|
3510
|
-
const [submitting, setSubmitting] =
|
|
3511
|
-
const [error, setError] =
|
|
3512
|
-
const [reasonOpen, setReasonOpen] =
|
|
3513
|
-
|
|
3594
|
+
const [details, setDetails] = React.useState("");
|
|
3595
|
+
const [submitting, setSubmitting] = React.useState(false);
|
|
3596
|
+
const [error, setError] = React.useState(null);
|
|
3597
|
+
const [reasonOpen, setReasonOpen] = React.useState(false);
|
|
3598
|
+
React.useEffect(() => {
|
|
3514
3599
|
if (open) {
|
|
3515
3600
|
setReason(NEGATIVE_FEEDBACK_REASONS[0].value);
|
|
3516
3601
|
setDetails("");
|
|
@@ -3519,7 +3604,7 @@ function FeedbackReasonModal({
|
|
|
3519
3604
|
setReasonOpen(false);
|
|
3520
3605
|
}
|
|
3521
3606
|
}, [open]);
|
|
3522
|
-
const handleKeyDown =
|
|
3607
|
+
const handleKeyDown = React.useCallback(
|
|
3523
3608
|
(event) => {
|
|
3524
3609
|
if (event.key !== "Escape") return;
|
|
3525
3610
|
if (reasonOpen) {
|
|
@@ -3530,7 +3615,7 @@ function FeedbackReasonModal({
|
|
|
3530
3615
|
},
|
|
3531
3616
|
[onClose, reasonOpen]
|
|
3532
3617
|
);
|
|
3533
|
-
|
|
3618
|
+
React.useEffect(() => {
|
|
3534
3619
|
if (!open || typeof document === "undefined") return;
|
|
3535
3620
|
document.addEventListener("keydown", handleKeyDown);
|
|
3536
3621
|
const previousOverflow = document.body.style.overflow;
|
|
@@ -3734,17 +3819,17 @@ function charDelay(char, speed, multiplier) {
|
|
|
3734
3819
|
function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDisplayedText, speedMultiplier = 1) {
|
|
3735
3820
|
const instant = speedMultiplier === 0;
|
|
3736
3821
|
const multiplier = instant ? 1 : Math.max(speedMultiplier, 0.1);
|
|
3737
|
-
const [displayedText, setDisplayedText] =
|
|
3738
|
-
const displayedRef =
|
|
3739
|
-
const targetRef =
|
|
3740
|
-
const enabledRef =
|
|
3741
|
-
const initialDisplayedRef =
|
|
3742
|
-
const timerRef =
|
|
3743
|
-
const runningRef =
|
|
3822
|
+
const [displayedText, setDisplayedText] = React.useState("");
|
|
3823
|
+
const displayedRef = React.useRef("");
|
|
3824
|
+
const targetRef = React.useRef(targetText);
|
|
3825
|
+
const enabledRef = React.useRef(enabled);
|
|
3826
|
+
const initialDisplayedRef = React.useRef(initialDisplayedText);
|
|
3827
|
+
const timerRef = React.useRef(null);
|
|
3828
|
+
const runningRef = React.useRef(false);
|
|
3744
3829
|
targetRef.current = targetText;
|
|
3745
3830
|
enabledRef.current = enabled;
|
|
3746
3831
|
initialDisplayedRef.current = initialDisplayedText;
|
|
3747
|
-
|
|
3832
|
+
React.useEffect(() => {
|
|
3748
3833
|
if (!enabled || instant) {
|
|
3749
3834
|
if (timerRef.current) {
|
|
3750
3835
|
clearTimeout(timerRef.current);
|
|
@@ -3834,26 +3919,26 @@ function AssistantMessageV2({
|
|
|
3834
3919
|
actions,
|
|
3835
3920
|
typingSpeed = 4
|
|
3836
3921
|
}) {
|
|
3837
|
-
const [copied, setCopied] =
|
|
3838
|
-
const [activeFeedback, setActiveFeedback] =
|
|
3922
|
+
const [copied, setCopied] = React.useState(false);
|
|
3923
|
+
const [activeFeedback, setActiveFeedback] = React.useState(
|
|
3839
3924
|
() => getFeedbackState(message)
|
|
3840
3925
|
);
|
|
3841
|
-
const [reasonModalOpen, setReasonModalOpen] =
|
|
3926
|
+
const [reasonModalOpen, setReasonModalOpen] = React.useState(false);
|
|
3842
3927
|
const canSubmitFeedback = !!onSubmitFeedback && !!message.executionId;
|
|
3843
|
-
const [toast, setToast] =
|
|
3844
|
-
const copyResetTimerRef =
|
|
3845
|
-
const toastTimerRef =
|
|
3928
|
+
const [toast, setToast] = React.useState(null);
|
|
3929
|
+
const copyResetTimerRef = React.useRef(null);
|
|
3930
|
+
const toastTimerRef = React.useRef(null);
|
|
3846
3931
|
const showCopyAction = actions?.copy ?? true;
|
|
3847
3932
|
const showTraceAction = (actions?.trace ?? true) && !!onExecutionTraceClick;
|
|
3848
3933
|
const showThumbsUp = actions?.thumbsUp ?? true;
|
|
3849
3934
|
const showThumbsDown = actions?.thumbsDown ?? true;
|
|
3850
3935
|
const hydratedFeedback = message.feedback;
|
|
3851
|
-
const hasEverStreamed =
|
|
3936
|
+
const hasEverStreamed = React.useRef(!!message.isStreaming);
|
|
3852
3937
|
if (message.isStreaming) hasEverStreamed.current = true;
|
|
3853
|
-
|
|
3938
|
+
React.useEffect(() => {
|
|
3854
3939
|
setActiveFeedback(getFeedbackState(message));
|
|
3855
3940
|
}, [hydratedFeedback, message.id]);
|
|
3856
|
-
|
|
3941
|
+
React.useEffect(() => {
|
|
3857
3942
|
return () => {
|
|
3858
3943
|
if (copyResetTimerRef.current) clearTimeout(copyResetTimerRef.current);
|
|
3859
3944
|
if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
|
|
@@ -4147,10 +4232,10 @@ function OtpInputV2({
|
|
|
4147
4232
|
disabled = false,
|
|
4148
4233
|
error = false
|
|
4149
4234
|
}) {
|
|
4150
|
-
const inputRefs =
|
|
4235
|
+
const inputRefs = React.useRef([]);
|
|
4151
4236
|
const safeMaxLength = Number.isInteger(maxLength) && maxLength > 0 ? Math.min(maxLength, MAX_SUPPORTED_LENGTH) : DEFAULT_MAX_LENGTH;
|
|
4152
4237
|
const digits = value.split("").concat(Array(safeMaxLength).fill("")).slice(0, safeMaxLength);
|
|
4153
|
-
|
|
4238
|
+
React.useEffect(() => {
|
|
4154
4239
|
if (disabled) return;
|
|
4155
4240
|
const timer = window.setTimeout(() => {
|
|
4156
4241
|
inputRefs.current[0]?.focus();
|
|
@@ -4249,31 +4334,31 @@ function VerificationInline({
|
|
|
4249
4334
|
onResend
|
|
4250
4335
|
}) {
|
|
4251
4336
|
const isNumeric = prompt.verificationType !== "ALPHANUMERIC_CODE";
|
|
4252
|
-
const codeLen =
|
|
4253
|
-
const [code, setCode] =
|
|
4254
|
-
const [errored, setErrored] =
|
|
4255
|
-
const [resendSec, setResendSec] =
|
|
4256
|
-
const [hiddenAfterResend, setHiddenAfterResend] =
|
|
4257
|
-
const lastSubmittedRef =
|
|
4258
|
-
const resendTimerRef =
|
|
4337
|
+
const codeLen = React.useMemo(() => codeLengthFromSchema(prompt), [prompt]);
|
|
4338
|
+
const [code, setCode] = React.useState("");
|
|
4339
|
+
const [errored, setErrored] = React.useState(false);
|
|
4340
|
+
const [resendSec, setResendSec] = React.useState(0);
|
|
4341
|
+
const [hiddenAfterResend, setHiddenAfterResend] = React.useState(false);
|
|
4342
|
+
const lastSubmittedRef = React.useRef(null);
|
|
4343
|
+
const resendTimerRef = React.useRef(void 0);
|
|
4259
4344
|
const status = prompt.status;
|
|
4260
4345
|
const busy = status === "submitting";
|
|
4261
4346
|
const stale = status === "stale";
|
|
4262
4347
|
const locked = busy || stale || expired;
|
|
4263
|
-
|
|
4348
|
+
React.useEffect(() => {
|
|
4264
4349
|
if (prompt.subAction === "SubmissionInvalid") {
|
|
4265
4350
|
setErrored(true);
|
|
4266
4351
|
setCode("");
|
|
4267
4352
|
lastSubmittedRef.current = null;
|
|
4268
4353
|
}
|
|
4269
4354
|
}, [prompt.subAction, prompt.userActionId]);
|
|
4270
|
-
|
|
4355
|
+
React.useEffect(() => {
|
|
4271
4356
|
setHiddenAfterResend(false);
|
|
4272
4357
|
}, [prompt.expirySeconds, prompt.message, prompt.subAction, prompt.userActionId]);
|
|
4273
|
-
|
|
4358
|
+
React.useEffect(() => {
|
|
4274
4359
|
if (code.length < codeLen) lastSubmittedRef.current = null;
|
|
4275
4360
|
}, [code, codeLen]);
|
|
4276
|
-
const doSubmit =
|
|
4361
|
+
const doSubmit = React.useCallback(
|
|
4277
4362
|
(value) => {
|
|
4278
4363
|
if (locked || !value) return;
|
|
4279
4364
|
if (lastSubmittedRef.current === value) return;
|
|
@@ -4285,20 +4370,20 @@ function VerificationInline({
|
|
|
4285
4370
|
},
|
|
4286
4371
|
[locked, onSubmit, prompt.userActionId]
|
|
4287
4372
|
);
|
|
4288
|
-
|
|
4373
|
+
React.useEffect(() => {
|
|
4289
4374
|
if (!isNumeric || locked) return;
|
|
4290
4375
|
if (code.length === codeLen && /^\d+$/.test(code)) {
|
|
4291
4376
|
doSubmit(code);
|
|
4292
4377
|
}
|
|
4293
4378
|
}, [code, codeLen, doSubmit, isNumeric, locked]);
|
|
4294
|
-
|
|
4379
|
+
React.useEffect(() => {
|
|
4295
4380
|
return () => {
|
|
4296
4381
|
if (typeof resendTimerRef.current === "number") {
|
|
4297
4382
|
window.clearInterval(resendTimerRef.current);
|
|
4298
4383
|
}
|
|
4299
4384
|
};
|
|
4300
4385
|
}, []);
|
|
4301
|
-
const startResendCooldown =
|
|
4386
|
+
const startResendCooldown = React.useCallback(() => {
|
|
4302
4387
|
setResendSec(RESEND_COOLDOWN_S);
|
|
4303
4388
|
if (typeof resendTimerRef.current === "number") {
|
|
4304
4389
|
window.clearInterval(resendTimerRef.current);
|
|
@@ -4316,7 +4401,7 @@ function VerificationInline({
|
|
|
4316
4401
|
});
|
|
4317
4402
|
}, 1e3);
|
|
4318
4403
|
}, []);
|
|
4319
|
-
const handleResend =
|
|
4404
|
+
const handleResend = React.useCallback(async () => {
|
|
4320
4405
|
if (locked || resendSec > 0) return;
|
|
4321
4406
|
setErrored(false);
|
|
4322
4407
|
setCode("");
|
|
@@ -4329,7 +4414,7 @@ function VerificationInline({
|
|
|
4329
4414
|
setHiddenAfterResend(false);
|
|
4330
4415
|
}
|
|
4331
4416
|
}, [locked, onResend, prompt.userActionId, resendSec, startResendCooldown]);
|
|
4332
|
-
const handleCancel =
|
|
4417
|
+
const handleCancel = React.useCallback(() => {
|
|
4333
4418
|
if (busy) return;
|
|
4334
4419
|
void onCancel(prompt.userActionId);
|
|
4335
4420
|
}, [busy, onCancel, prompt.userActionId]);
|
|
@@ -4419,13 +4504,13 @@ function SchemaFormInline({
|
|
|
4419
4504
|
onCancel
|
|
4420
4505
|
}) {
|
|
4421
4506
|
const schema = prompt.requestedSchema;
|
|
4422
|
-
const fields =
|
|
4423
|
-
const [values, setValues] =
|
|
4507
|
+
const fields = React.useMemo(() => renderableFields(schema), [schema]);
|
|
4508
|
+
const [values, setValues] = React.useState(() => {
|
|
4424
4509
|
const init2 = {};
|
|
4425
4510
|
for (const [key, field] of fields) init2[key] = defaultValueFor(field);
|
|
4426
4511
|
return init2;
|
|
4427
4512
|
});
|
|
4428
|
-
const [errors, setErrors] =
|
|
4513
|
+
const [errors, setErrors] = React.useState({});
|
|
4429
4514
|
const status = prompt.status;
|
|
4430
4515
|
const busy = status === "submitting";
|
|
4431
4516
|
const stale = status === "stale";
|
|
@@ -4566,8 +4651,8 @@ function NotificationInline({ notification, onDismiss }) {
|
|
|
4566
4651
|
}
|
|
4567
4652
|
function useExpiryCountdown(prompt) {
|
|
4568
4653
|
const initial = typeof prompt.expirySeconds === "number" && prompt.expirySeconds > 0 ? Math.floor(prompt.expirySeconds) : void 0;
|
|
4569
|
-
const [secondsLeft, setSecondsLeft] =
|
|
4570
|
-
|
|
4654
|
+
const [secondsLeft, setSecondsLeft] = React.useState(initial);
|
|
4655
|
+
React.useEffect(() => {
|
|
4571
4656
|
if (initial === void 0) {
|
|
4572
4657
|
setSecondsLeft(void 0);
|
|
4573
4658
|
return;
|
|
@@ -4606,7 +4691,7 @@ function UserActionInline({
|
|
|
4606
4691
|
onExpired
|
|
4607
4692
|
}) {
|
|
4608
4693
|
const [secondsLeft, expired] = useExpiryCountdown(prompt);
|
|
4609
|
-
|
|
4694
|
+
React.useEffect(() => {
|
|
4610
4695
|
if (expired && prompt.kind !== "notification") onExpired?.();
|
|
4611
4696
|
}, [expired, onExpired, prompt.kind]);
|
|
4612
4697
|
let body;
|
|
@@ -4669,7 +4754,7 @@ function getPromptViewKey(prompt) {
|
|
|
4669
4754
|
prompt.message ?? ""
|
|
4670
4755
|
].join(PROMPT_KEY_SEPARATOR);
|
|
4671
4756
|
}
|
|
4672
|
-
var MessageListV2 =
|
|
4757
|
+
var MessageListV2 = React.forwardRef(
|
|
4673
4758
|
function MessageListV22({
|
|
4674
4759
|
messages,
|
|
4675
4760
|
isStreaming = false,
|
|
@@ -4689,25 +4774,25 @@ var MessageListV2 = react.forwardRef(
|
|
|
4689
4774
|
onSubmitFeedback,
|
|
4690
4775
|
typingSpeed = 4
|
|
4691
4776
|
}, ref) {
|
|
4692
|
-
const noop =
|
|
4777
|
+
const noop = React.useCallback(async () => {
|
|
4693
4778
|
}, []);
|
|
4694
|
-
const scrollRef =
|
|
4695
|
-
const scrollInnerRef =
|
|
4696
|
-
const isNearBottomRef =
|
|
4697
|
-
const [showScrollBtn, setShowScrollBtn] =
|
|
4698
|
-
const [expiredPromptViewState, setExpiredPromptViewState] =
|
|
4699
|
-
const expiredUserActionIdsRef =
|
|
4700
|
-
const prevCountRef =
|
|
4701
|
-
const pauseStickUntilUserMessageRef =
|
|
4702
|
-
const followingBottomRef =
|
|
4703
|
-
const lastPinAtRef =
|
|
4704
|
-
const prevScrollTopRef =
|
|
4705
|
-
const getDistanceFromBottom =
|
|
4779
|
+
const scrollRef = React.useRef(null);
|
|
4780
|
+
const scrollInnerRef = React.useRef(null);
|
|
4781
|
+
const isNearBottomRef = React.useRef(true);
|
|
4782
|
+
const [showScrollBtn, setShowScrollBtn] = React.useState(false);
|
|
4783
|
+
const [expiredPromptViewState, setExpiredPromptViewState] = React.useState({});
|
|
4784
|
+
const expiredUserActionIdsRef = React.useRef(/* @__PURE__ */ new Set());
|
|
4785
|
+
const prevCountRef = React.useRef(messages.length);
|
|
4786
|
+
const pauseStickUntilUserMessageRef = React.useRef(false);
|
|
4787
|
+
const followingBottomRef = React.useRef(true);
|
|
4788
|
+
const lastPinAtRef = React.useRef(0);
|
|
4789
|
+
const prevScrollTopRef = React.useRef(0);
|
|
4790
|
+
const getDistanceFromBottom = React.useCallback(() => {
|
|
4706
4791
|
const el = scrollRef.current;
|
|
4707
4792
|
if (!el) return 0;
|
|
4708
4793
|
return el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
4709
4794
|
}, []);
|
|
4710
|
-
const messageActivityFingerprint =
|
|
4795
|
+
const messageActivityFingerprint = React.useMemo(() => {
|
|
4711
4796
|
const last = messages[messages.length - 1];
|
|
4712
4797
|
const promptFingerprint = (userActionPrompts ?? []).map((prompt) => `${getPromptViewKey(prompt)}:${prompt.status}`).join(PROMPT_KEY_SEPARATOR);
|
|
4713
4798
|
const notificationFingerprint = (notifications ?? []).map((notification) => notification.id).join(PROMPT_KEY_SEPARATOR);
|
|
@@ -4733,7 +4818,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4733
4818
|
notificationFingerprint
|
|
4734
4819
|
].join(PROMPT_KEY_SEPARATOR);
|
|
4735
4820
|
}, [isStreaming, messages, notifications, userActionPrompts]);
|
|
4736
|
-
const handleUserActionExpired =
|
|
4821
|
+
const handleUserActionExpired = React.useCallback(
|
|
4737
4822
|
(promptKey, userActionId) => {
|
|
4738
4823
|
setExpiredPromptViewState((prev) => {
|
|
4739
4824
|
if (prev[promptKey]) return prev;
|
|
@@ -4750,7 +4835,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4750
4835
|
},
|
|
4751
4836
|
[messageActivityFingerprint, onExpireUserAction]
|
|
4752
4837
|
);
|
|
4753
|
-
|
|
4838
|
+
React.useEffect(() => {
|
|
4754
4839
|
setExpiredPromptViewState((prev) => {
|
|
4755
4840
|
let changed = false;
|
|
4756
4841
|
const next = {};
|
|
@@ -4765,7 +4850,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4765
4850
|
return changed ? next : prev;
|
|
4766
4851
|
});
|
|
4767
4852
|
}, [messageActivityFingerprint]);
|
|
4768
|
-
|
|
4853
|
+
React.useEffect(() => {
|
|
4769
4854
|
const livePromptKeys = new Set((userActionPrompts ?? []).map(getPromptViewKey));
|
|
4770
4855
|
const liveUserActionIds = new Set((userActionPrompts ?? []).map((p) => p.userActionId));
|
|
4771
4856
|
for (const userActionId of expiredUserActionIdsRef.current) {
|
|
@@ -4786,21 +4871,21 @@ var MessageListV2 = react.forwardRef(
|
|
|
4786
4871
|
return changed ? next : prev;
|
|
4787
4872
|
});
|
|
4788
4873
|
}, [userActionPrompts]);
|
|
4789
|
-
const visibleUserActionPrompts =
|
|
4874
|
+
const visibleUserActionPrompts = React.useMemo(
|
|
4790
4875
|
() => userActionPrompts?.filter((prompt) => {
|
|
4791
4876
|
const promptKey = getPromptViewKey(prompt);
|
|
4792
4877
|
return !expiredPromptViewState[promptKey]?.hidden;
|
|
4793
4878
|
}),
|
|
4794
4879
|
[expiredPromptViewState, userActionPrompts]
|
|
4795
4880
|
);
|
|
4796
|
-
const pinToBottom =
|
|
4881
|
+
const pinToBottom = React.useCallback((behavior = "instant") => {
|
|
4797
4882
|
const el = scrollRef.current;
|
|
4798
4883
|
if (!el) return;
|
|
4799
4884
|
lastPinAtRef.current = performance.now();
|
|
4800
4885
|
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
4801
4886
|
prevScrollTopRef.current = el.scrollHeight;
|
|
4802
4887
|
}, []);
|
|
4803
|
-
const scrollToBottom =
|
|
4888
|
+
const scrollToBottom = React.useCallback(
|
|
4804
4889
|
(behavior = "smooth") => {
|
|
4805
4890
|
const el = scrollRef.current;
|
|
4806
4891
|
if (!el) return;
|
|
@@ -4810,7 +4895,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4810
4895
|
},
|
|
4811
4896
|
[pinToBottom]
|
|
4812
4897
|
);
|
|
4813
|
-
|
|
4898
|
+
React.useImperativeHandle(
|
|
4814
4899
|
ref,
|
|
4815
4900
|
() => ({
|
|
4816
4901
|
scrollToBottom: (behavior = "smooth") => {
|
|
@@ -4823,7 +4908,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4823
4908
|
}),
|
|
4824
4909
|
[scrollToBottom]
|
|
4825
4910
|
);
|
|
4826
|
-
const handleScroll =
|
|
4911
|
+
const handleScroll = React.useCallback(() => {
|
|
4827
4912
|
const el = scrollRef.current;
|
|
4828
4913
|
if (!el) return;
|
|
4829
4914
|
const currentScrollTop = el.scrollTop;
|
|
@@ -4844,7 +4929,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4844
4929
|
pauseStickUntilUserMessageRef.current = false;
|
|
4845
4930
|
}
|
|
4846
4931
|
}, [getDistanceFromBottom]);
|
|
4847
|
-
|
|
4932
|
+
React.useEffect(() => {
|
|
4848
4933
|
const prevCount = prevCountRef.current;
|
|
4849
4934
|
prevCountRef.current = messages.length;
|
|
4850
4935
|
if (messages.length > prevCount) {
|
|
@@ -4858,7 +4943,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4858
4943
|
}
|
|
4859
4944
|
}
|
|
4860
4945
|
}, [messages.length, scrollToBottom]);
|
|
4861
|
-
|
|
4946
|
+
React.useEffect(() => {
|
|
4862
4947
|
const inner = scrollInnerRef.current;
|
|
4863
4948
|
if (!inner) return;
|
|
4864
4949
|
const pinIfFollowing = () => {
|
|
@@ -4883,7 +4968,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4883
4968
|
mo.disconnect();
|
|
4884
4969
|
};
|
|
4885
4970
|
}, [pinToBottom]);
|
|
4886
|
-
|
|
4971
|
+
React.useEffect(() => {
|
|
4887
4972
|
if (messages.length > 0) {
|
|
4888
4973
|
setTimeout(() => scrollToBottom("instant"), 50);
|
|
4889
4974
|
}
|
|
@@ -4972,7 +5057,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4972
5057
|
] });
|
|
4973
5058
|
}
|
|
4974
5059
|
);
|
|
4975
|
-
var ChatInputV2 =
|
|
5060
|
+
var ChatInputV2 = React.forwardRef(
|
|
4976
5061
|
function ChatInputV22({
|
|
4977
5062
|
onSend,
|
|
4978
5063
|
disabled = false,
|
|
@@ -4996,20 +5081,20 @@ var ChatInputV2 = react.forwardRef(
|
|
|
4996
5081
|
onAnalysisModeChange,
|
|
4997
5082
|
slashCommands = []
|
|
4998
5083
|
}, ref) {
|
|
4999
|
-
const [value, setValue] =
|
|
5000
|
-
const [isFocused, setIsFocused] =
|
|
5001
|
-
const [showActions, setShowActions] =
|
|
5002
|
-
const [showVoiceTooltip, setShowVoiceTooltip] =
|
|
5003
|
-
const [selectedCommandIndex, setSelectedCommandIndex] =
|
|
5004
|
-
const [inlineHint, setInlineHint] =
|
|
5005
|
-
const [commandMenuDismissed, setCommandMenuDismissed] =
|
|
5006
|
-
const textareaRef =
|
|
5007
|
-
const actionsRef =
|
|
5008
|
-
const preRecordTextRef =
|
|
5009
|
-
const voiceTooltipTimerRef =
|
|
5084
|
+
const [value, setValue] = React.useState("");
|
|
5085
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
5086
|
+
const [showActions, setShowActions] = React.useState(false);
|
|
5087
|
+
const [showVoiceTooltip, setShowVoiceTooltip] = React.useState(false);
|
|
5088
|
+
const [selectedCommandIndex, setSelectedCommandIndex] = React.useState(0);
|
|
5089
|
+
const [inlineHint, setInlineHint] = React.useState(null);
|
|
5090
|
+
const [commandMenuDismissed, setCommandMenuDismissed] = React.useState(false);
|
|
5091
|
+
const textareaRef = React.useRef(null);
|
|
5092
|
+
const actionsRef = React.useRef(null);
|
|
5093
|
+
const preRecordTextRef = React.useRef("");
|
|
5094
|
+
const voiceTooltipTimerRef = React.useRef(
|
|
5010
5095
|
null
|
|
5011
5096
|
);
|
|
5012
|
-
const voiceDraftSyncActiveRef =
|
|
5097
|
+
const voiceDraftSyncActiveRef = React.useRef(false);
|
|
5013
5098
|
const isInputLocked = disabled || isRecording;
|
|
5014
5099
|
const hasAttachmentOptions = showUploadImageButton || showAttachFileButton;
|
|
5015
5100
|
const showAttachmentMenuButton = showAttachmentButton && hasAttachmentOptions;
|
|
@@ -5020,14 +5105,14 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5020
5105
|
(command) => command.name.toLowerCase().startsWith(commandQuery)
|
|
5021
5106
|
);
|
|
5022
5107
|
const showCommandSuggestions = !commandMenuDismissed && !isRecording && !disabled && commandSuggestions.length > 0;
|
|
5023
|
-
|
|
5108
|
+
React.useEffect(() => {
|
|
5024
5109
|
if (textareaRef.current) {
|
|
5025
5110
|
textareaRef.current.style.height = "auto";
|
|
5026
5111
|
const scrollHeight = textareaRef.current.scrollHeight;
|
|
5027
5112
|
textareaRef.current.style.height = `${Math.min(scrollHeight, 200)}px`;
|
|
5028
5113
|
}
|
|
5029
5114
|
}, [value]);
|
|
5030
|
-
|
|
5115
|
+
React.useEffect(() => {
|
|
5031
5116
|
if (disabled) {
|
|
5032
5117
|
setIsFocused(false);
|
|
5033
5118
|
setShowActions(false);
|
|
@@ -5037,7 +5122,7 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5037
5122
|
const frameId = requestAnimationFrame(() => textareaRef.current?.focus());
|
|
5038
5123
|
return () => cancelAnimationFrame(frameId);
|
|
5039
5124
|
}, [disabled]);
|
|
5040
|
-
|
|
5125
|
+
React.useImperativeHandle(
|
|
5041
5126
|
ref,
|
|
5042
5127
|
() => ({
|
|
5043
5128
|
setDraft: (message) => {
|
|
@@ -5054,7 +5139,7 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5054
5139
|
}),
|
|
5055
5140
|
[disabled]
|
|
5056
5141
|
);
|
|
5057
|
-
|
|
5142
|
+
React.useEffect(() => {
|
|
5058
5143
|
if (!showActions) return;
|
|
5059
5144
|
const handleClickOutside = (e) => {
|
|
5060
5145
|
if (actionsRef.current && !actionsRef.current.contains(e.target)) {
|
|
@@ -5064,29 +5149,29 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5064
5149
|
document.addEventListener("mousedown", handleClickOutside);
|
|
5065
5150
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
5066
5151
|
}, [showActions]);
|
|
5067
|
-
|
|
5152
|
+
React.useEffect(() => {
|
|
5068
5153
|
if (!showAttachmentMenuButton) {
|
|
5069
5154
|
setShowActions(false);
|
|
5070
5155
|
}
|
|
5071
5156
|
}, [showAttachmentMenuButton]);
|
|
5072
|
-
|
|
5157
|
+
React.useEffect(() => {
|
|
5073
5158
|
setSelectedCommandIndex(0);
|
|
5074
5159
|
setCommandMenuDismissed(false);
|
|
5075
5160
|
}, [commandQuery]);
|
|
5076
|
-
|
|
5161
|
+
React.useEffect(() => {
|
|
5077
5162
|
return () => {
|
|
5078
5163
|
if (voiceTooltipTimerRef.current) {
|
|
5079
5164
|
clearTimeout(voiceTooltipTimerRef.current);
|
|
5080
5165
|
}
|
|
5081
5166
|
};
|
|
5082
5167
|
}, []);
|
|
5083
|
-
|
|
5168
|
+
React.useEffect(() => {
|
|
5084
5169
|
if (!voiceDraftSyncActiveRef.current) return;
|
|
5085
5170
|
const base = preRecordTextRef.current;
|
|
5086
5171
|
const separator = base && !base.endsWith(" ") && transcribedText ? " " : "";
|
|
5087
5172
|
setValue(`${base}${separator}${transcribedText}`);
|
|
5088
5173
|
}, [isRecording, transcribedText]);
|
|
5089
|
-
const handleSend =
|
|
5174
|
+
const handleSend = React.useCallback(() => {
|
|
5090
5175
|
if (!value.trim() || disabled) return;
|
|
5091
5176
|
const commandHint = getSlashCommandValidationHint(value);
|
|
5092
5177
|
if (commandHint) {
|
|
@@ -5106,7 +5191,7 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5106
5191
|
}
|
|
5107
5192
|
});
|
|
5108
5193
|
}, [value, disabled, onClearEditing, onSend]);
|
|
5109
|
-
const selectCommand =
|
|
5194
|
+
const selectCommand = React.useCallback(
|
|
5110
5195
|
(command) => {
|
|
5111
5196
|
const insertText = command.insertText ?? `${command.name} `;
|
|
5112
5197
|
setValue(insertText);
|
|
@@ -5162,14 +5247,14 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5162
5247
|
onAttachFileClick?.();
|
|
5163
5248
|
setShowActions(false);
|
|
5164
5249
|
};
|
|
5165
|
-
const hideVoiceTooltip =
|
|
5250
|
+
const hideVoiceTooltip = React.useCallback(() => {
|
|
5166
5251
|
if (voiceTooltipTimerRef.current) {
|
|
5167
5252
|
clearTimeout(voiceTooltipTimerRef.current);
|
|
5168
5253
|
voiceTooltipTimerRef.current = null;
|
|
5169
5254
|
}
|
|
5170
5255
|
setShowVoiceTooltip(false);
|
|
5171
5256
|
}, []);
|
|
5172
|
-
const startVoiceTooltipTimer =
|
|
5257
|
+
const startVoiceTooltipTimer = React.useCallback(() => {
|
|
5173
5258
|
if (isVoiceButtonDisabled || isRecording) return;
|
|
5174
5259
|
if (voiceTooltipTimerRef.current) {
|
|
5175
5260
|
clearTimeout(voiceTooltipTimerRef.current);
|
|
@@ -5491,9 +5576,9 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5491
5576
|
var thinking_atom_default = "data:application/zip;base64,UEsDBBQAAAAIAMWrkFzFrMWzUgAAAF4AAAANAAAAbWFuaWZlc3QuanNvbqtWKkstKs7Mz1OyUjJS0lFKT81LLUosyS8C8h1S8kty8ktKMlP14SzdrGIHQz0zPZDaxLzM3MQSoN5iJavoaqXMFKAe38TMPIXgZKApSrWxtQBQSwMEFAAAAAgAxauQXLRghFpXBAAA1RwAABEAAABhL01haW4gU2NlbmUuanNvbu1YWW/jNhD+KwafJVWkqMtPbdEDfdiiQIq+GMZCcei1GvmApLRdGP7v/YYiddqbGNumR4wcomZGHM7B76N0ZLstm7N3Wb6b3a3UTjGHPTw8sLnvsA2bCx/X3811q+qMzY/sAx74stjXda7WeaGqL1alyup9OeNeEnmcnRxWZB9VWbH54sjqj2weOI2bH5+KYibhoirZnONSa0f7AzykGOQYkGP4X2dFpbq13ONx0mTVu6x6bNXZXosf4erI9OLwjwRw7Tv4WWLSP+ALa7I2Rs0RkvkzRhEZQdWz8iHCms48Z54RMEAs2gABkcGRYVFHBqXv8Sh2GBKgRzDNW00SIClag1GzugVNShk5OUd9zxMj4cI/2UhoSdUwVBJpn53EGPMTOd0hh8hAUwuodC1UoVZ1ud+9UjWog+jvb6hIv9D9egxT8aK8kfte5tD5kiTYCfpaqvUPyABb7beH9/57zlUi4zBwE+FnrsyUdDOfC/c+iNVqzVOVKoH06vwLLDsr1Y6q+VZLgX7+dxQDW29SDGmKsVNPr1iLSyB1Bkui0CDGAEdkEmmpeXghQwe/Td0slnRzyDQ5NwdH8L05htXHLGFqIWk0fQ+YPhc9P3+3VpvsoDrSYR9KFNHWpKvWdgfdV998/e3sF2w70Nb35f7pAFNdfn0z49QpNLHDVnqh0FL9IUXU1kG1eZmDO1rYzB06+imrN30/hNG9JmkiPLIVm9flE2ZFuRZoFzf0hIyXzkJfqXcgtLJGCSHyi1SR/URF9pNJYP8b2adeaEwwoqc6AQ2XS+obXTi7bdi6eGmWs8MmXyEN3+UFPaOzQGOdBcQ52BeeDGXqgB3jRNIlirBe7Vs2TYNkXeiGsFtcTS0w3XLPAp8x0MQ86uluEVPse66t9R4ZdbVd88Vw4tNpqTcZIZekEUrFQi/2fAS3hqPIwBMXSIqBp6yqVN1shjHH5NejpvUyOtdZzNyX93lNVfwPn+vGrHjDpiuxSXAvFIHDhSdFRNghvcSPnMQLhKRbo3dbg0bvNgYWsZ4xcz7txuIYrGOfOzz0/JiTUZB4acwdVwiNa43abfVGrbVnMA79fCXG3WGvPdLLlM5nc6czWiBpKFXxq07ptqBOudg7hDI49vRUOAJYuJggZiQDrqFSxA6CMgj2/8PCNqDty6oCjqlViaL8XOb0iC4JjWfU51Xb6CiLunz8CiPop0cnnIb6Ryd7YGpf4bqTUmhPSpSSYXxuSsBtk3ztGkQwPAJS7QevkWdOa2SLNLSn378smfqMTZF0yRzV8Ez4SToNf4i5drmWByfHdk1B5PxGQW+Xgix5jMlhTB5jchlS0CeNOiK74GREQROOGVLQhKFuFHSjoH+CgkSELwM3CrqCgjDJGQoKbhT0pikIH0oE+CAMgOmpF3HAof580grxHaWRdt9opjr9wWUyj6UWHnvSD4yZ1N9pBiIXshuF3Cjktd9izmHo61CIxeSAPpWd/gRQSwECFAAUAAAACADFq5BcxazFs1IAAABeAAAADQAAAAAAAAAAAAAAAAAAAAAAbWFuaWZlc3QuanNvblBLAQIUABQAAAAIAMWrkFy0YIRaVwQAANUcAAARAAAAAAAAAAAAAAAAAH0AAABhL01haW4gU2NlbmUuanNvblBLBQYAAAAAAgACAHoAAAADBQAAAAA=";
|
|
5492
5577
|
var DEFAULT_SIZE = 36;
|
|
5493
5578
|
function useElapsedSeconds(isStreaming) {
|
|
5494
|
-
const [elapsed, setElapsed] =
|
|
5495
|
-
const startRef =
|
|
5496
|
-
|
|
5579
|
+
const [elapsed, setElapsed] = React.useState(0);
|
|
5580
|
+
const startRef = React.useRef(null);
|
|
5581
|
+
React.useEffect(() => {
|
|
5497
5582
|
if (!isStreaming) {
|
|
5498
5583
|
startRef.current = null;
|
|
5499
5584
|
setElapsed(0);
|
|
@@ -5552,22 +5637,22 @@ function StreamingIndicatorV2({
|
|
|
5552
5637
|
) });
|
|
5553
5638
|
}
|
|
5554
5639
|
function ImageLightboxV2({ src, alt, onClose }) {
|
|
5555
|
-
const [isMounted, setIsMounted] =
|
|
5556
|
-
const [isImageLoaded, setIsImageLoaded] =
|
|
5557
|
-
|
|
5640
|
+
const [isMounted, setIsMounted] = React.useState(false);
|
|
5641
|
+
const [isImageLoaded, setIsImageLoaded] = React.useState(false);
|
|
5642
|
+
React.useEffect(() => {
|
|
5558
5643
|
setIsMounted(true);
|
|
5559
5644
|
return () => setIsMounted(false);
|
|
5560
5645
|
}, []);
|
|
5561
|
-
|
|
5646
|
+
React.useEffect(() => {
|
|
5562
5647
|
setIsImageLoaded(false);
|
|
5563
5648
|
}, [src]);
|
|
5564
|
-
const handleKeyDown =
|
|
5649
|
+
const handleKeyDown = React.useCallback(
|
|
5565
5650
|
(e) => {
|
|
5566
5651
|
if (e.key === "Escape") onClose();
|
|
5567
5652
|
},
|
|
5568
5653
|
[onClose]
|
|
5569
5654
|
);
|
|
5570
|
-
|
|
5655
|
+
React.useEffect(() => {
|
|
5571
5656
|
if (!src || typeof document === "undefined") return;
|
|
5572
5657
|
document.addEventListener("keydown", handleKeyDown);
|
|
5573
5658
|
const previousOverflow = document.body.style.overflow;
|
|
@@ -5716,10 +5801,10 @@ function TraceTimelineModal({
|
|
|
5716
5801
|
apiBaseUrl,
|
|
5717
5802
|
apiHeaders
|
|
5718
5803
|
}) {
|
|
5719
|
-
const [trace, setTrace] =
|
|
5720
|
-
const [loading, setLoading] =
|
|
5721
|
-
const [error, setError] =
|
|
5722
|
-
|
|
5804
|
+
const [trace, setTrace] = React.useState(null);
|
|
5805
|
+
const [loading, setLoading] = React.useState(false);
|
|
5806
|
+
const [error, setError] = React.useState(null);
|
|
5807
|
+
React.useEffect(() => {
|
|
5723
5808
|
if (!open || !executionId) return;
|
|
5724
5809
|
const ctrl = new AbortController();
|
|
5725
5810
|
setLoading(true);
|
|
@@ -5741,7 +5826,7 @@ function TraceTimelineModal({
|
|
|
5741
5826
|
}).finally(() => setLoading(false));
|
|
5742
5827
|
return () => ctrl.abort();
|
|
5743
5828
|
}, [open, executionId, apiBaseUrl, apiHeaders]);
|
|
5744
|
-
const totalMs =
|
|
5829
|
+
const totalMs = React.useMemo(() => {
|
|
5745
5830
|
if (!trace) return 0;
|
|
5746
5831
|
const meta = trace.runMetadata?.totalTimeMs;
|
|
5747
5832
|
if (typeof meta === "number" && meta > 0) return meta;
|
|
@@ -5750,7 +5835,7 @@ function TraceTimelineModal({
|
|
|
5750
5835
|
if (starts.length === 0 || ends.length === 0) return 0;
|
|
5751
5836
|
return Math.max(...ends) - Math.min(...starts);
|
|
5752
5837
|
}, [trace]);
|
|
5753
|
-
const accountedMs =
|
|
5838
|
+
const accountedMs = React.useMemo(
|
|
5754
5839
|
() => (trace?.pipelineSteps ?? []).reduce(
|
|
5755
5840
|
(sum, s) => sum + (s.durationMs ?? 0),
|
|
5756
5841
|
0
|
|
@@ -6011,12 +6096,12 @@ var NOOP_ASYNC = async () => {
|
|
|
6011
6096
|
var NOOP = () => {
|
|
6012
6097
|
};
|
|
6013
6098
|
function useSentryChatCallbacks(callbacks, config) {
|
|
6014
|
-
const sentryCtxRef =
|
|
6015
|
-
const callbacksRef =
|
|
6099
|
+
const sentryCtxRef = React.useRef({});
|
|
6100
|
+
const callbacksRef = React.useRef(callbacks);
|
|
6016
6101
|
callbacksRef.current = callbacks;
|
|
6017
6102
|
const initialSessionId = config.initialSessionId;
|
|
6018
6103
|
const apiHeaders = config.api.headers;
|
|
6019
|
-
|
|
6104
|
+
React.useEffect(() => {
|
|
6020
6105
|
sentryCtxRef.current.agentId = config.agentId;
|
|
6021
6106
|
sentryCtxRef.current.sessionOwnerId = config.sessionParams?.id;
|
|
6022
6107
|
if (initialSessionId) {
|
|
@@ -6032,13 +6117,13 @@ function useSentryChatCallbacks(callbacks, config) {
|
|
|
6032
6117
|
initialSessionId,
|
|
6033
6118
|
apiHeaders
|
|
6034
6119
|
]);
|
|
6035
|
-
|
|
6120
|
+
React.useEffect(() => {
|
|
6036
6121
|
const endpoint = config.api.streamEndpoint || "/api/playground/ask/stream";
|
|
6037
6122
|
return subscribeToCfRay(endpoint, (cfRay) => {
|
|
6038
6123
|
sentryCtxRef.current.cfRay = cfRay;
|
|
6039
6124
|
});
|
|
6040
6125
|
}, [config.api.streamEndpoint]);
|
|
6041
|
-
return
|
|
6126
|
+
return React.useMemo(
|
|
6042
6127
|
() => ({
|
|
6043
6128
|
onMessageSent: (msg) => callbacksRef.current?.onMessageSent?.(msg),
|
|
6044
6129
|
onStreamStart: () => callbacksRef.current?.onStreamStart?.(),
|
|
@@ -6087,7 +6172,7 @@ function useSentryChatCallbacks(callbacks, config) {
|
|
|
6087
6172
|
[]
|
|
6088
6173
|
);
|
|
6089
6174
|
}
|
|
6090
|
-
var PaymanChatInner =
|
|
6175
|
+
var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
|
|
6091
6176
|
config,
|
|
6092
6177
|
callbacks = {},
|
|
6093
6178
|
className,
|
|
@@ -6098,18 +6183,18 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6098
6183
|
hasMoreMessages = false,
|
|
6099
6184
|
chat
|
|
6100
6185
|
}, ref) {
|
|
6101
|
-
const [inputValue, setInputValue] =
|
|
6102
|
-
const prevInputValueRef =
|
|
6103
|
-
const [hasEverSentMessage, setHasEverSentMessage] =
|
|
6104
|
-
const [lightboxSrc, setLightboxSrc] =
|
|
6105
|
-
const [lightboxAlt, setLightboxAlt] =
|
|
6106
|
-
const [editingMessageId, setEditingMessageId] =
|
|
6107
|
-
const [isResetSessionConfirmOpen, setIsResetSessionConfirmOpen] =
|
|
6108
|
-
const [analysisMode, setAnalysisMode] =
|
|
6109
|
-
const chatInputV2Ref =
|
|
6110
|
-
const messageListV2Ref =
|
|
6111
|
-
const resetToEmptyStateRef =
|
|
6112
|
-
|
|
6186
|
+
const [inputValue, setInputValue] = React.useState("");
|
|
6187
|
+
const prevInputValueRef = React.useRef(inputValue);
|
|
6188
|
+
const [hasEverSentMessage, setHasEverSentMessage] = React.useState(false);
|
|
6189
|
+
const [lightboxSrc, setLightboxSrc] = React.useState(null);
|
|
6190
|
+
const [lightboxAlt, setLightboxAlt] = React.useState("");
|
|
6191
|
+
const [editingMessageId, setEditingMessageId] = React.useState(null);
|
|
6192
|
+
const [isResetSessionConfirmOpen, setIsResetSessionConfirmOpen] = React.useState(false);
|
|
6193
|
+
const [analysisMode, setAnalysisMode] = React.useState("fast");
|
|
6194
|
+
const chatInputV2Ref = React.useRef(null);
|
|
6195
|
+
const messageListV2Ref = React.useRef(null);
|
|
6196
|
+
const resetToEmptyStateRef = React.useRef(false);
|
|
6197
|
+
React.useEffect(() => {
|
|
6113
6198
|
if (config.sentryDsn) {
|
|
6114
6199
|
initSentryIfNeeded(config.sentryDsn);
|
|
6115
6200
|
}
|
|
@@ -6125,7 +6210,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6125
6210
|
getSessionId,
|
|
6126
6211
|
getMessages
|
|
6127
6212
|
} = chat;
|
|
6128
|
-
|
|
6213
|
+
React.useEffect(() => {
|
|
6129
6214
|
if (resetToEmptyStateRef.current) {
|
|
6130
6215
|
if (messages.length === 0) {
|
|
6131
6216
|
setHasEverSentMessage(false);
|
|
@@ -6137,7 +6222,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6137
6222
|
setHasEverSentMessage(true);
|
|
6138
6223
|
}
|
|
6139
6224
|
}, [messages.length, hasEverSentMessage]);
|
|
6140
|
-
|
|
6225
|
+
React.useEffect(() => {
|
|
6141
6226
|
if (!editingMessageId) return;
|
|
6142
6227
|
const editingMessageStillExists = messages.some(
|
|
6143
6228
|
(message) => message.id === editingMessageId && message.role === "user"
|
|
@@ -6176,7 +6261,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6176
6261
|
}
|
|
6177
6262
|
}
|
|
6178
6263
|
);
|
|
6179
|
-
const contextValue =
|
|
6264
|
+
const contextValue = React.useMemo(
|
|
6180
6265
|
() => ({
|
|
6181
6266
|
resetSession,
|
|
6182
6267
|
clearMessages,
|
|
@@ -6203,8 +6288,8 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6203
6288
|
onAttachFileClick,
|
|
6204
6289
|
onMessageFeedback
|
|
6205
6290
|
} = callbacks;
|
|
6206
|
-
const [debugTraceExecutionId, setDebugTraceExecutionId] =
|
|
6207
|
-
const handleSubmitFeedback =
|
|
6291
|
+
const [debugTraceExecutionId, setDebugTraceExecutionId] = React.useState(null);
|
|
6292
|
+
const handleSubmitFeedback = React.useCallback(
|
|
6208
6293
|
async ({ messageId, executionId, feedback, details }) => {
|
|
6209
6294
|
if (!executionId) {
|
|
6210
6295
|
throw new Error("Cannot submit feedback before the response completes");
|
|
@@ -6235,14 +6320,14 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6235
6320
|
onMessageFeedback
|
|
6236
6321
|
]
|
|
6237
6322
|
);
|
|
6238
|
-
const onExecutionTraceClick =
|
|
6323
|
+
const onExecutionTraceClick = React.useMemo(() => {
|
|
6239
6324
|
if (!config.debug) return rawOnExecutionTraceClick;
|
|
6240
6325
|
return (data) => {
|
|
6241
6326
|
rawOnExecutionTraceClick?.(data);
|
|
6242
6327
|
if (data.executionId) setDebugTraceExecutionId(data.executionId);
|
|
6243
6328
|
};
|
|
6244
6329
|
}, [config.debug, rawOnExecutionTraceClick]);
|
|
6245
|
-
const performResetSession =
|
|
6330
|
+
const performResetSession = React.useCallback(() => {
|
|
6246
6331
|
resetToEmptyStateRef.current = true;
|
|
6247
6332
|
setEditingMessageId(null);
|
|
6248
6333
|
setIsResetSessionConfirmOpen(false);
|
|
@@ -6263,13 +6348,13 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6263
6348
|
resetSession,
|
|
6264
6349
|
stopRecording
|
|
6265
6350
|
]);
|
|
6266
|
-
const requestResetSession =
|
|
6351
|
+
const requestResetSession = React.useCallback(() => {
|
|
6267
6352
|
setIsResetSessionConfirmOpen(true);
|
|
6268
6353
|
}, []);
|
|
6269
|
-
const closeResetSessionConfirm =
|
|
6354
|
+
const closeResetSessionConfirm = React.useCallback(() => {
|
|
6270
6355
|
setIsResetSessionConfirmOpen(false);
|
|
6271
6356
|
}, []);
|
|
6272
|
-
|
|
6357
|
+
React.useImperativeHandle(ref, () => ({
|
|
6273
6358
|
resetSession: performResetSession,
|
|
6274
6359
|
clearMessages,
|
|
6275
6360
|
cancelStream,
|
|
@@ -6308,7 +6393,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6308
6393
|
slashCommands: slashCommandsConfig,
|
|
6309
6394
|
commandPermissions
|
|
6310
6395
|
} = config;
|
|
6311
|
-
const messageActions =
|
|
6396
|
+
const messageActions = React.useMemo(
|
|
6312
6397
|
() => ({
|
|
6313
6398
|
userMessageActions: {
|
|
6314
6399
|
copy: messageActionsConfig?.userMessageActions?.copy ?? true,
|
|
@@ -6324,18 +6409,18 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6324
6409
|
}),
|
|
6325
6410
|
[messageActionsConfig]
|
|
6326
6411
|
);
|
|
6327
|
-
const slashCommands =
|
|
6412
|
+
const slashCommands = React.useMemo(
|
|
6328
6413
|
() => enableSlashCommands ? filterSlashCommands(
|
|
6329
6414
|
slashCommandsConfig ?? DEFAULT_SLASH_COMMANDS,
|
|
6330
6415
|
commandPermissions
|
|
6331
6416
|
) : [],
|
|
6332
6417
|
[commandPermissions, enableSlashCommands, slashCommandsConfig]
|
|
6333
6418
|
);
|
|
6334
|
-
const isSessionParamsConfigured =
|
|
6419
|
+
const isSessionParamsConfigured = React.useMemo(() => {
|
|
6335
6420
|
if (!sessionParams) return false;
|
|
6336
6421
|
return !!(sessionParams.id?.trim() && sessionParams.name?.trim());
|
|
6337
6422
|
}, [sessionParams?.id, sessionParams?.name]);
|
|
6338
|
-
|
|
6423
|
+
React.useEffect(() => {
|
|
6339
6424
|
const wasEmpty = prevInputValueRef.current.trim() === "";
|
|
6340
6425
|
const isEmpty2 = inputValue.trim() === "";
|
|
6341
6426
|
prevInputValueRef.current = inputValue;
|
|
@@ -6402,7 +6487,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6402
6487
|
void sendMessage(text.trim(), { analysisMode: effectiveAnalysisMode });
|
|
6403
6488
|
}
|
|
6404
6489
|
};
|
|
6405
|
-
const handleVoicePress =
|
|
6490
|
+
const handleVoicePress = React.useCallback(async () => {
|
|
6406
6491
|
if (!voiceAvailable) return;
|
|
6407
6492
|
if (isRecording) {
|
|
6408
6493
|
stopRecording();
|
|
@@ -6411,7 +6496,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6411
6496
|
clearTranscript();
|
|
6412
6497
|
await startRecording();
|
|
6413
6498
|
}, [clearTranscript, isRecording, startRecording, stopRecording, voiceAvailable]);
|
|
6414
|
-
const handleEditMessageDraft =
|
|
6499
|
+
const handleEditMessageDraft = React.useCallback((messageId) => {
|
|
6415
6500
|
const targetMessage = messages.find((message) => message.id === messageId);
|
|
6416
6501
|
if (!targetMessage?.content.trim()) return;
|
|
6417
6502
|
setEditingMessageId(messageId);
|
|
@@ -6420,7 +6505,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6420
6505
|
messageListV2Ref.current?.scrollToBottom("smooth");
|
|
6421
6506
|
});
|
|
6422
6507
|
}, [messages]);
|
|
6423
|
-
const handleRetryUserMessage =
|
|
6508
|
+
const handleRetryUserMessage = React.useCallback((messageId) => {
|
|
6424
6509
|
if (isWaitingForResponse) return;
|
|
6425
6510
|
const targetMessage = messages.find(
|
|
6426
6511
|
(message) => message.id === messageId && message.role === "user"
|
|
@@ -6437,7 +6522,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6437
6522
|
});
|
|
6438
6523
|
});
|
|
6439
6524
|
}, [isWaitingForResponse, messages, sendMessage, effectiveAnalysisMode]);
|
|
6440
|
-
const handleClearEditing =
|
|
6525
|
+
const handleClearEditing = React.useCallback(() => {
|
|
6441
6526
|
setEditingMessageId(null);
|
|
6442
6527
|
}, []);
|
|
6443
6528
|
return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -6627,7 +6712,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6627
6712
|
}
|
|
6628
6713
|
) });
|
|
6629
6714
|
});
|
|
6630
|
-
var PaymanChat =
|
|
6715
|
+
var PaymanChat = React.forwardRef(
|
|
6631
6716
|
function PaymanChat2(props, ref) {
|
|
6632
6717
|
const mergedCallbacks = useSentryChatCallbacks(props.callbacks, props.config);
|
|
6633
6718
|
const chat = useChatV2(props.config, mergedCallbacks);
|