@paymanai/payman-ask-sdk 4.0.25 → 4.0.26
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 +396 -268
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +136 -8
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +25 -4
- package/dist/index.native.js.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);
|
|
@@ -300,6 +301,8 @@ function getEventMessage(event) {
|
|
|
300
301
|
}
|
|
301
302
|
case "RUN_IN_PROGRESS":
|
|
302
303
|
return event.partialText || "Thinking...";
|
|
304
|
+
case "LLM_CALL_STARTED":
|
|
305
|
+
return event.description || "";
|
|
303
306
|
case "RUN_COMPLETED":
|
|
304
307
|
return "Agent run completed";
|
|
305
308
|
case "RUN_FAILED":
|
|
@@ -437,7 +440,8 @@ function createInitialV2State() {
|
|
|
437
440
|
finalData: void 0,
|
|
438
441
|
steps: [],
|
|
439
442
|
stepCounter: 0,
|
|
440
|
-
currentExecutingStepId: void 0
|
|
443
|
+
currentExecutingStepId: void 0,
|
|
444
|
+
trailingActivity: false
|
|
441
445
|
};
|
|
442
446
|
}
|
|
443
447
|
function upsertUserAction(state, req) {
|
|
@@ -459,6 +463,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
459
463
|
if (typeof eventType === "string" && eventType.toUpperCase() === "KEEP_ALIVE") {
|
|
460
464
|
if (event.executionId) state.executionId = event.executionId;
|
|
461
465
|
if (event.sessionId) state.sessionId = event.sessionId;
|
|
466
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
462
467
|
const description = typeof event.description === "string" ? event.description : "";
|
|
463
468
|
if (description) {
|
|
464
469
|
for (let i = state.steps.length - 1; i >= 0; i--) {
|
|
@@ -493,7 +498,12 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
493
498
|
state.lastEventType = eventType;
|
|
494
499
|
break;
|
|
495
500
|
}
|
|
501
|
+
case "LLM_CALL_STARTED":
|
|
502
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
503
|
+
state.lastEventType = eventType;
|
|
504
|
+
break;
|
|
496
505
|
case "INTENT_STARTED": {
|
|
506
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
497
507
|
const stepId = `step-${state.stepCounter++}`;
|
|
498
508
|
state.steps.push({
|
|
499
509
|
id: stepId,
|
|
@@ -509,6 +519,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
509
519
|
break;
|
|
510
520
|
}
|
|
511
521
|
case "INTENT_COMPLETED": {
|
|
522
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
512
523
|
const intentStep = state.steps.find((s) => s.eventType === "INTENT_STARTED" && s.status === "in_progress");
|
|
513
524
|
if (intentStep) {
|
|
514
525
|
intentStep.status = "completed";
|
|
@@ -540,6 +551,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
540
551
|
step2.status = "completed";
|
|
541
552
|
}
|
|
542
553
|
});
|
|
554
|
+
state.trailingActivity = false;
|
|
543
555
|
state.lastEventType = eventType;
|
|
544
556
|
break;
|
|
545
557
|
}
|
|
@@ -611,6 +623,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
611
623
|
case "WORKFLOW_ERROR":
|
|
612
624
|
state.hasError = true;
|
|
613
625
|
state.errorMessage = event.errorMessage || event.message || "Workflow error";
|
|
626
|
+
state.trailingActivity = false;
|
|
614
627
|
state.lastEventType = eventType;
|
|
615
628
|
break;
|
|
616
629
|
// ---- K2 pipeline stage lifecycle events ----
|
|
@@ -853,12 +866,12 @@ async function resolveRagImageUrls(config, content, signal) {
|
|
|
853
866
|
}
|
|
854
867
|
var FRIENDLY_ERROR_MESSAGE = "Oops, something went wrong. Please try again.";
|
|
855
868
|
function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForResponse) {
|
|
856
|
-
const abortControllerRef =
|
|
857
|
-
const configRef =
|
|
869
|
+
const abortControllerRef = React.useRef(null);
|
|
870
|
+
const configRef = React.useRef(config);
|
|
858
871
|
configRef.current = config;
|
|
859
|
-
const callbacksRef =
|
|
872
|
+
const callbacksRef = React.useRef(callbacks);
|
|
860
873
|
callbacksRef.current = callbacks;
|
|
861
|
-
const startStream =
|
|
874
|
+
const startStream = React.useCallback(
|
|
862
875
|
async (userMessage, streamingId, sessionId, externalAbortController, options) => {
|
|
863
876
|
abortControllerRef.current?.abort();
|
|
864
877
|
const abortController = externalAbortController ?? new AbortController();
|
|
@@ -899,7 +912,9 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
899
912
|
const latestUsefulStep = [...state.steps].reverse().find(
|
|
900
913
|
(s) => s.message && !isBlandStatus(s.message)
|
|
901
914
|
);
|
|
902
|
-
const
|
|
915
|
+
const eventTypeUpper = typeof event.eventType === "string" ? event.eventType.toUpperCase() : "";
|
|
916
|
+
const liveEventLabel = eventTypeUpper === "KEEP_ALIVE" || eventTypeUpper === "LLM_CALL_STARTED" ? useful(getEventMessage(event)) : void 0;
|
|
917
|
+
const currentMessage = useful(activeStep?.message) ?? useful(lastInProgressStep?.message) ?? liveEventLabel ?? latestUsefulStep?.message ?? useful(getEventMessage(event)) ?? // Last-resort: every candidate is bland (very first event,
|
|
903
918
|
// nothing useful seen yet). Render the bland label so the
|
|
904
919
|
// bubble isn't blank.
|
|
905
920
|
activeStep?.message ?? lastInProgressStep?.message ?? getEventMessage(event);
|
|
@@ -924,6 +939,7 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
924
939
|
streamingContent: state.finalResponse,
|
|
925
940
|
content: "",
|
|
926
941
|
currentMessage,
|
|
942
|
+
hasTrailingActivity: state.trailingActivity,
|
|
927
943
|
streamProgress: "processing",
|
|
928
944
|
isError: false,
|
|
929
945
|
steps: [...state.steps],
|
|
@@ -1057,7 +1073,7 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
1057
1073
|
},
|
|
1058
1074
|
[setMessages, setIsWaitingForResponse]
|
|
1059
1075
|
);
|
|
1060
|
-
const cancelStream =
|
|
1076
|
+
const cancelStream = React.useCallback(() => {
|
|
1061
1077
|
abortControllerRef.current?.abort();
|
|
1062
1078
|
}, []);
|
|
1063
1079
|
return {
|
|
@@ -1168,24 +1184,24 @@ function getSessionIdFromMessages(messages) {
|
|
|
1168
1184
|
return messages.find((message) => message.sessionId)?.sessionId;
|
|
1169
1185
|
}
|
|
1170
1186
|
function useChatV2(config, callbacks = {}) {
|
|
1171
|
-
const [messages, setMessages] =
|
|
1172
|
-
const [isWaitingForResponse, setIsWaitingForResponse] =
|
|
1187
|
+
const [messages, setMessages] = React.useState(() => getStoredOrInitialMessages(config));
|
|
1188
|
+
const [isWaitingForResponse, setIsWaitingForResponse] = React.useState(() => {
|
|
1173
1189
|
if (!config.userId) return false;
|
|
1174
1190
|
return activeStreamStore.get(config.userId)?.isWaiting ?? false;
|
|
1175
1191
|
});
|
|
1176
|
-
const sessionIdRef =
|
|
1192
|
+
const sessionIdRef = React.useRef(
|
|
1177
1193
|
getSessionIdFromMessages(getStoredOrInitialMessages(config)) ?? config.initialSessionId ?? void 0
|
|
1178
1194
|
);
|
|
1179
|
-
const prevUserIdRef =
|
|
1180
|
-
const streamUserIdRef =
|
|
1181
|
-
const subscriptionPrevUserIdRef =
|
|
1182
|
-
const callbacksRef =
|
|
1195
|
+
const prevUserIdRef = React.useRef(config.userId);
|
|
1196
|
+
const streamUserIdRef = React.useRef(void 0);
|
|
1197
|
+
const subscriptionPrevUserIdRef = React.useRef(config.userId);
|
|
1198
|
+
const callbacksRef = React.useRef(callbacks);
|
|
1183
1199
|
callbacksRef.current = callbacks;
|
|
1184
|
-
const configRef =
|
|
1200
|
+
const configRef = React.useRef(config);
|
|
1185
1201
|
configRef.current = config;
|
|
1186
|
-
const messagesRef =
|
|
1202
|
+
const messagesRef = React.useRef(messages);
|
|
1187
1203
|
messagesRef.current = messages;
|
|
1188
|
-
const storeAwareSetMessages =
|
|
1204
|
+
const storeAwareSetMessages = React.useCallback(
|
|
1189
1205
|
(updater) => {
|
|
1190
1206
|
const streamUserId = streamUserIdRef.current;
|
|
1191
1207
|
const currentUserId = configRef.current.userId;
|
|
@@ -1200,7 +1216,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1200
1216
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1201
1217
|
[]
|
|
1202
1218
|
);
|
|
1203
|
-
const storeAwareSetIsWaiting =
|
|
1219
|
+
const storeAwareSetIsWaiting = React.useCallback(
|
|
1204
1220
|
(waiting) => {
|
|
1205
1221
|
const streamUserId = streamUserIdRef.current;
|
|
1206
1222
|
const currentUserId = configRef.current.userId;
|
|
@@ -1215,11 +1231,11 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1215
1231
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1216
1232
|
[]
|
|
1217
1233
|
);
|
|
1218
|
-
const [userActionState, setUserActionState] =
|
|
1234
|
+
const [userActionState, setUserActionState] = React.useState(() => {
|
|
1219
1235
|
if (!config.userId) return EMPTY_USER_ACTION_STATE2;
|
|
1220
1236
|
return activeStreamStore.get(config.userId)?.userActionState ?? EMPTY_USER_ACTION_STATE2;
|
|
1221
1237
|
});
|
|
1222
|
-
const storeAwareSetUserActionState =
|
|
1238
|
+
const storeAwareSetUserActionState = React.useCallback(
|
|
1223
1239
|
(updater) => {
|
|
1224
1240
|
const streamUserId = streamUserIdRef.current;
|
|
1225
1241
|
const currentUserId = configRef.current.userId;
|
|
@@ -1237,7 +1253,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1237
1253
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1238
1254
|
[]
|
|
1239
1255
|
);
|
|
1240
|
-
const wrappedCallbacks =
|
|
1256
|
+
const wrappedCallbacks = React.useMemo(() => ({
|
|
1241
1257
|
...callbacksRef.current,
|
|
1242
1258
|
onMessageSent: (message) => callbacksRef.current.onMessageSent?.(message),
|
|
1243
1259
|
onStreamStart: () => callbacksRef.current.onStreamStart?.(),
|
|
@@ -1266,7 +1282,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1266
1282
|
storeAwareSetMessages,
|
|
1267
1283
|
storeAwareSetIsWaiting
|
|
1268
1284
|
);
|
|
1269
|
-
const sendMessage =
|
|
1285
|
+
const sendMessage = React.useCallback(
|
|
1270
1286
|
async (userMessage, options) => {
|
|
1271
1287
|
if (!userMessage.trim()) return;
|
|
1272
1288
|
if (!sessionIdRef.current && configRef.current.autoGenerateSessionId !== false) {
|
|
@@ -1326,16 +1342,16 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1326
1342
|
},
|
|
1327
1343
|
[startStream]
|
|
1328
1344
|
);
|
|
1329
|
-
const clearMessages =
|
|
1345
|
+
const clearMessages = React.useCallback(() => {
|
|
1330
1346
|
if (configRef.current.userId) {
|
|
1331
1347
|
chatStore.delete(configRef.current.userId);
|
|
1332
1348
|
}
|
|
1333
1349
|
setMessages([]);
|
|
1334
1350
|
}, []);
|
|
1335
|
-
const prependMessages =
|
|
1351
|
+
const prependMessages = React.useCallback((msgs) => {
|
|
1336
1352
|
setMessages((prev) => [...msgs, ...prev]);
|
|
1337
1353
|
}, []);
|
|
1338
|
-
const cancelStream =
|
|
1354
|
+
const cancelStream = React.useCallback(() => {
|
|
1339
1355
|
const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
|
|
1340
1356
|
if (streamUserId) {
|
|
1341
1357
|
activeStreamStore.abort(streamUserId);
|
|
@@ -1359,7 +1375,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1359
1375
|
})
|
|
1360
1376
|
);
|
|
1361
1377
|
}, [cancelStreamManager, storeAwareSetUserActionState]);
|
|
1362
|
-
const resetSession =
|
|
1378
|
+
const resetSession = React.useCallback(() => {
|
|
1363
1379
|
const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
|
|
1364
1380
|
if (streamUserId) {
|
|
1365
1381
|
activeStreamStore.abort(streamUserId);
|
|
@@ -1374,13 +1390,13 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1374
1390
|
setIsWaitingForResponse(false);
|
|
1375
1391
|
storeAwareSetUserActionState(EMPTY_USER_ACTION_STATE2);
|
|
1376
1392
|
}, []);
|
|
1377
|
-
const getSessionId =
|
|
1393
|
+
const getSessionId = React.useCallback(() => {
|
|
1378
1394
|
return sessionIdRef.current;
|
|
1379
1395
|
}, []);
|
|
1380
|
-
const getMessages =
|
|
1396
|
+
const getMessages = React.useCallback(() => {
|
|
1381
1397
|
return messages;
|
|
1382
1398
|
}, [messages]);
|
|
1383
|
-
const setPromptStatus =
|
|
1399
|
+
const setPromptStatus = React.useCallback(
|
|
1384
1400
|
(userActionId, status) => {
|
|
1385
1401
|
storeAwareSetUserActionState((prev) => ({
|
|
1386
1402
|
...prev,
|
|
@@ -1391,13 +1407,13 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1391
1407
|
},
|
|
1392
1408
|
[storeAwareSetUserActionState]
|
|
1393
1409
|
);
|
|
1394
|
-
const removePrompt =
|
|
1410
|
+
const removePrompt = React.useCallback((userActionId) => {
|
|
1395
1411
|
storeAwareSetUserActionState((prev) => ({
|
|
1396
1412
|
...prev,
|
|
1397
1413
|
prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
|
|
1398
1414
|
}));
|
|
1399
1415
|
}, [storeAwareSetUserActionState]);
|
|
1400
|
-
const submitUserAction2 =
|
|
1416
|
+
const submitUserAction2 = React.useCallback(
|
|
1401
1417
|
async (userActionId, content) => {
|
|
1402
1418
|
setPromptStatus(userActionId, "submitting");
|
|
1403
1419
|
try {
|
|
@@ -1415,7 +1431,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1415
1431
|
},
|
|
1416
1432
|
[removePrompt, setPromptStatus]
|
|
1417
1433
|
);
|
|
1418
|
-
const cancelUserAction2 =
|
|
1434
|
+
const cancelUserAction2 = React.useCallback(
|
|
1419
1435
|
async (userActionId) => {
|
|
1420
1436
|
setPromptStatus(userActionId, "submitting");
|
|
1421
1437
|
try {
|
|
@@ -1433,7 +1449,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1433
1449
|
},
|
|
1434
1450
|
[removePrompt, setPromptStatus]
|
|
1435
1451
|
);
|
|
1436
|
-
const resendUserAction2 =
|
|
1452
|
+
const resendUserAction2 = React.useCallback(
|
|
1437
1453
|
async (userActionId) => {
|
|
1438
1454
|
setPromptStatus(userActionId, "submitting");
|
|
1439
1455
|
try {
|
|
@@ -1451,7 +1467,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1451
1467
|
},
|
|
1452
1468
|
[setPromptStatus]
|
|
1453
1469
|
);
|
|
1454
|
-
const expireUserAction2 =
|
|
1470
|
+
const expireUserAction2 = React.useCallback(
|
|
1455
1471
|
async (userActionId) => {
|
|
1456
1472
|
setPromptStatus(userActionId, "expired");
|
|
1457
1473
|
try {
|
|
@@ -1464,13 +1480,13 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1464
1480
|
},
|
|
1465
1481
|
[setPromptStatus]
|
|
1466
1482
|
);
|
|
1467
|
-
const dismissNotification =
|
|
1483
|
+
const dismissNotification = React.useCallback((id) => {
|
|
1468
1484
|
storeAwareSetUserActionState((prev) => ({
|
|
1469
1485
|
...prev,
|
|
1470
1486
|
notifications: prev.notifications.filter((n) => n.id !== id)
|
|
1471
1487
|
}));
|
|
1472
1488
|
}, [storeAwareSetUserActionState]);
|
|
1473
|
-
|
|
1489
|
+
React.useEffect(() => {
|
|
1474
1490
|
const prevSubscriptionUserId = subscriptionPrevUserIdRef.current;
|
|
1475
1491
|
subscriptionPrevUserIdRef.current = config.userId;
|
|
1476
1492
|
const { userId } = config;
|
|
@@ -1492,7 +1508,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1492
1508
|
}
|
|
1493
1509
|
return unsubscribe;
|
|
1494
1510
|
}, [config.userId]);
|
|
1495
|
-
|
|
1511
|
+
React.useEffect(() => {
|
|
1496
1512
|
if (!config.userId) return;
|
|
1497
1513
|
if (prevUserIdRef.current !== config.userId) return;
|
|
1498
1514
|
const toSave = messages.filter((m) => !m.isStreaming);
|
|
@@ -1500,14 +1516,14 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1500
1516
|
chatStore.set(config.userId, toSave);
|
|
1501
1517
|
}
|
|
1502
1518
|
}, [messages, config.userId]);
|
|
1503
|
-
|
|
1519
|
+
React.useEffect(() => {
|
|
1504
1520
|
if (!config.userId || activeStreamStore.has(config.userId)) return;
|
|
1505
1521
|
if (!config.initialMessages?.length || messagesRef.current.length > 0) return;
|
|
1506
1522
|
chatStore.set(config.userId, config.initialMessages);
|
|
1507
1523
|
setMessages(config.initialMessages);
|
|
1508
1524
|
sessionIdRef.current = getSessionIdFromMessages(config.initialMessages) ?? config.initialSessionId;
|
|
1509
1525
|
}, [config.initialMessages, config.initialSessionId, config.userId]);
|
|
1510
|
-
|
|
1526
|
+
React.useEffect(() => {
|
|
1511
1527
|
const prevUserId = prevUserIdRef.current;
|
|
1512
1528
|
prevUserIdRef.current = config.userId;
|
|
1513
1529
|
if (prevUserId === config.userId) return;
|
|
@@ -1557,12 +1573,12 @@ function getSpeechRecognition() {
|
|
|
1557
1573
|
return window.SpeechRecognition || window.webkitSpeechRecognition || null;
|
|
1558
1574
|
}
|
|
1559
1575
|
function useVoice(config = {}, callbacks = {}) {
|
|
1560
|
-
const [voiceState, setVoiceState] =
|
|
1561
|
-
const [transcribedText, setTranscribedText] =
|
|
1562
|
-
const [isAvailable, setIsAvailable] =
|
|
1563
|
-
const [isRecording, setIsRecording] =
|
|
1564
|
-
const recognitionRef =
|
|
1565
|
-
const autoStopTimerRef =
|
|
1576
|
+
const [voiceState, setVoiceState] = React.useState("idle");
|
|
1577
|
+
const [transcribedText, setTranscribedText] = React.useState("");
|
|
1578
|
+
const [isAvailable, setIsAvailable] = React.useState(false);
|
|
1579
|
+
const [isRecording, setIsRecording] = React.useState(false);
|
|
1580
|
+
const recognitionRef = React.useRef(null);
|
|
1581
|
+
const autoStopTimerRef = React.useRef(null);
|
|
1566
1582
|
const {
|
|
1567
1583
|
lang = "en-US",
|
|
1568
1584
|
interimResults = true,
|
|
@@ -1571,14 +1587,14 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1571
1587
|
autoStopAfterSilence
|
|
1572
1588
|
} = config;
|
|
1573
1589
|
const { onStart, onEnd, onResult, onError, onStateChange } = callbacks;
|
|
1574
|
-
|
|
1590
|
+
React.useEffect(() => {
|
|
1575
1591
|
const SpeechRecognitionAPI = getSpeechRecognition();
|
|
1576
1592
|
setIsAvailable(SpeechRecognitionAPI !== null);
|
|
1577
1593
|
}, []);
|
|
1578
|
-
|
|
1594
|
+
React.useEffect(() => {
|
|
1579
1595
|
onStateChange?.(voiceState);
|
|
1580
1596
|
}, [voiceState, onStateChange]);
|
|
1581
|
-
const requestPermissions =
|
|
1597
|
+
const requestPermissions = React.useCallback(async () => {
|
|
1582
1598
|
try {
|
|
1583
1599
|
const result = await navigator.mediaDevices.getUserMedia({
|
|
1584
1600
|
audio: true
|
|
@@ -1595,7 +1611,7 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1595
1611
|
};
|
|
1596
1612
|
}
|
|
1597
1613
|
}, []);
|
|
1598
|
-
const getPermissions =
|
|
1614
|
+
const getPermissions = React.useCallback(async () => {
|
|
1599
1615
|
if (typeof navigator === "undefined" || !navigator.permissions) {
|
|
1600
1616
|
return {
|
|
1601
1617
|
granted: false,
|
|
@@ -1617,13 +1633,13 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1617
1633
|
};
|
|
1618
1634
|
}
|
|
1619
1635
|
}, []);
|
|
1620
|
-
const clearAutoStopTimer =
|
|
1636
|
+
const clearAutoStopTimer = React.useCallback(() => {
|
|
1621
1637
|
if (autoStopTimerRef.current) {
|
|
1622
1638
|
clearTimeout(autoStopTimerRef.current);
|
|
1623
1639
|
autoStopTimerRef.current = null;
|
|
1624
1640
|
}
|
|
1625
1641
|
}, []);
|
|
1626
|
-
const resetAutoStopTimer =
|
|
1642
|
+
const resetAutoStopTimer = React.useCallback(() => {
|
|
1627
1643
|
clearAutoStopTimer();
|
|
1628
1644
|
if (autoStopAfterSilence && autoStopAfterSilence > 0) {
|
|
1629
1645
|
autoStopTimerRef.current = setTimeout(() => {
|
|
@@ -1633,7 +1649,7 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1633
1649
|
}, autoStopAfterSilence);
|
|
1634
1650
|
}
|
|
1635
1651
|
}, [autoStopAfterSilence, clearAutoStopTimer, isRecording]);
|
|
1636
|
-
const stopRecording =
|
|
1652
|
+
const stopRecording = React.useCallback(() => {
|
|
1637
1653
|
if (recognitionRef.current) {
|
|
1638
1654
|
try {
|
|
1639
1655
|
recognitionRef.current.stop();
|
|
@@ -1645,7 +1661,7 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1645
1661
|
setIsRecording(false);
|
|
1646
1662
|
setVoiceState("idle");
|
|
1647
1663
|
}, [clearAutoStopTimer]);
|
|
1648
|
-
const startRecording =
|
|
1664
|
+
const startRecording = React.useCallback(async () => {
|
|
1649
1665
|
const SpeechRecognitionAPI = getSpeechRecognition();
|
|
1650
1666
|
if (!SpeechRecognitionAPI) {
|
|
1651
1667
|
onError?.("Speech recognition not supported in this browser");
|
|
@@ -1735,15 +1751,15 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1735
1751
|
resetAutoStopTimer,
|
|
1736
1752
|
clearAutoStopTimer
|
|
1737
1753
|
]);
|
|
1738
|
-
const clearTranscript =
|
|
1754
|
+
const clearTranscript = React.useCallback(() => {
|
|
1739
1755
|
setTranscribedText("");
|
|
1740
1756
|
}, []);
|
|
1741
|
-
const reset =
|
|
1757
|
+
const reset = React.useCallback(() => {
|
|
1742
1758
|
stopRecording();
|
|
1743
1759
|
setTranscribedText("");
|
|
1744
1760
|
setVoiceState("idle");
|
|
1745
1761
|
}, [stopRecording]);
|
|
1746
|
-
|
|
1762
|
+
React.useEffect(() => {
|
|
1747
1763
|
return () => {
|
|
1748
1764
|
if (recognitionRef.current) {
|
|
1749
1765
|
try {
|
|
@@ -1883,9 +1899,9 @@ function buildContent(schema, values) {
|
|
|
1883
1899
|
}
|
|
1884
1900
|
return content;
|
|
1885
1901
|
}
|
|
1886
|
-
var PaymanChatContext =
|
|
1902
|
+
var PaymanChatContext = React.createContext(void 0);
|
|
1887
1903
|
function usePaymanChat() {
|
|
1888
|
-
const context =
|
|
1904
|
+
const context = React.useContext(PaymanChatContext);
|
|
1889
1905
|
if (!context) {
|
|
1890
1906
|
throw new Error("usePaymanChat must be used within a PaymanChat component");
|
|
1891
1907
|
}
|
|
@@ -2082,6 +2098,9 @@ function getConflictErrorMessage(errorDetails) {
|
|
|
2082
2098
|
}
|
|
2083
2099
|
function initSentryIfNeeded(dsn) {
|
|
2084
2100
|
if (!dsn) return;
|
|
2101
|
+
if (typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1")) {
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2085
2104
|
if (Sentry__namespace.getClient()) return;
|
|
2086
2105
|
Sentry__namespace.init({
|
|
2087
2106
|
dsn,
|
|
@@ -2143,8 +2162,8 @@ function ImageLightbox({
|
|
|
2143
2162
|
alt = "",
|
|
2144
2163
|
onClose
|
|
2145
2164
|
}) {
|
|
2146
|
-
const [isMounted, setIsMounted] =
|
|
2147
|
-
const [isImageLoaded, setIsImageLoaded] =
|
|
2165
|
+
const [isMounted, setIsMounted] = React.useState(false);
|
|
2166
|
+
const [isImageLoaded, setIsImageLoaded] = React.useState(false);
|
|
2148
2167
|
const overlayStyle = {
|
|
2149
2168
|
position: "fixed",
|
|
2150
2169
|
inset: 0,
|
|
@@ -2165,14 +2184,14 @@ function ImageLightbox({
|
|
|
2165
2184
|
justifyContent: "center",
|
|
2166
2185
|
overflow: "hidden"
|
|
2167
2186
|
};
|
|
2168
|
-
|
|
2187
|
+
React.useEffect(() => {
|
|
2169
2188
|
setIsMounted(true);
|
|
2170
2189
|
return () => setIsMounted(false);
|
|
2171
2190
|
}, []);
|
|
2172
|
-
|
|
2191
|
+
React.useEffect(() => {
|
|
2173
2192
|
setIsImageLoaded(false);
|
|
2174
2193
|
}, [src]);
|
|
2175
|
-
|
|
2194
|
+
React.useEffect(() => {
|
|
2176
2195
|
if (typeof document === "undefined") return;
|
|
2177
2196
|
const previousOverflow = document.body.style.overflow;
|
|
2178
2197
|
document.body.style.overflow = "hidden";
|
|
@@ -2180,7 +2199,7 @@ function ImageLightbox({
|
|
|
2180
2199
|
document.body.style.overflow = previousOverflow;
|
|
2181
2200
|
};
|
|
2182
2201
|
}, []);
|
|
2183
|
-
|
|
2202
|
+
React.useEffect(() => {
|
|
2184
2203
|
if (typeof document === "undefined") return;
|
|
2185
2204
|
const handleKeyDown = (event) => {
|
|
2186
2205
|
if (event.key === "Escape") {
|
|
@@ -2276,15 +2295,15 @@ function MarkdownImage({
|
|
|
2276
2295
|
maxHeight: "18rem",
|
|
2277
2296
|
objectFit: "contain"
|
|
2278
2297
|
};
|
|
2279
|
-
const [isLoaded, setIsLoaded] =
|
|
2280
|
-
const [hasError, setHasError] =
|
|
2281
|
-
const [isLightboxOpen, setIsLightboxOpen] =
|
|
2282
|
-
const isUnresolvedRagImage =
|
|
2298
|
+
const [isLoaded, setIsLoaded] = React.useState(false);
|
|
2299
|
+
const [hasError, setHasError] = React.useState(false);
|
|
2300
|
+
const [isLightboxOpen, setIsLightboxOpen] = React.useState(false);
|
|
2301
|
+
const isUnresolvedRagImage = React.useMemo(
|
|
2283
2302
|
() => src ? isUnresolvedRagImageSource(src) : false,
|
|
2284
2303
|
[src]
|
|
2285
2304
|
);
|
|
2286
2305
|
const isResolvingRagImage = isResolving && isUnresolvedRagImage;
|
|
2287
|
-
|
|
2306
|
+
React.useEffect(() => {
|
|
2288
2307
|
setIsLoaded(false);
|
|
2289
2308
|
setHasError(false);
|
|
2290
2309
|
setIsLightboxOpen(false);
|
|
@@ -2411,9 +2430,9 @@ function AgentMessage({
|
|
|
2411
2430
|
const hasTraceData = !!(message.tracingData || message.executionId) && !isStreaming;
|
|
2412
2431
|
const isCancelled = message.isCancelled ?? false;
|
|
2413
2432
|
const currentExecutingStepId = message.currentExecutingStepId;
|
|
2414
|
-
const [isStepsExpanded, setIsStepsExpanded] =
|
|
2415
|
-
const wasStreamingRef =
|
|
2416
|
-
|
|
2433
|
+
const [isStepsExpanded, setIsStepsExpanded] = React.useState(false);
|
|
2434
|
+
const wasStreamingRef = React.useRef(isStreaming);
|
|
2435
|
+
React.useEffect(() => {
|
|
2417
2436
|
if (isStreaming && hasSteps) {
|
|
2418
2437
|
setIsStepsExpanded(true);
|
|
2419
2438
|
}
|
|
@@ -2430,13 +2449,13 @@ function AgentMessage({
|
|
|
2430
2449
|
const completedWithNoContent = !isStreaming && !isCancelled && content.length === 0 && (message.streamProgress === "completed" || message.streamProgress === "error");
|
|
2431
2450
|
const conflictErrorMessage = getConflictErrorMessage(message.errorDetails);
|
|
2432
2451
|
const isError = !!conflictErrorMessage || (isFriendlyWorkflowError(message.errorDetails) || looksLikeRawError(content)) && !hasMeaningfulContent || completedWithNoContent;
|
|
2433
|
-
const currentStep =
|
|
2452
|
+
const currentStep = React.useMemo(
|
|
2434
2453
|
() => message.steps?.find(
|
|
2435
2454
|
(s) => s.id === currentExecutingStepId && s.status === "in_progress"
|
|
2436
2455
|
),
|
|
2437
2456
|
[message.steps, currentExecutingStepId]
|
|
2438
2457
|
);
|
|
2439
|
-
const markdownRenderers =
|
|
2458
|
+
const markdownRenderers = React.useMemo(
|
|
2440
2459
|
() => createMarkdownComponents({
|
|
2441
2460
|
isResolvingImages: message.isResolvingImages
|
|
2442
2461
|
}),
|
|
@@ -2510,8 +2529,8 @@ function AgentMessage({
|
|
|
2510
2529
|
}) })
|
|
2511
2530
|
}
|
|
2512
2531
|
) });
|
|
2513
|
-
const stepsToggleRef =
|
|
2514
|
-
const handleStepsToggle =
|
|
2532
|
+
const stepsToggleRef = React.useRef(null);
|
|
2533
|
+
const handleStepsToggle = React.useCallback(() => {
|
|
2515
2534
|
setIsStepsExpanded((prev) => {
|
|
2516
2535
|
const next = !prev;
|
|
2517
2536
|
if (next) {
|
|
@@ -2839,23 +2858,23 @@ function MessageList({
|
|
|
2839
2858
|
isLoadingMoreMessages = false,
|
|
2840
2859
|
hasMoreMessages = false
|
|
2841
2860
|
}) {
|
|
2842
|
-
const scrollRef =
|
|
2843
|
-
const isNearBottomRef =
|
|
2844
|
-
const [showScrollBtn, setShowScrollBtn] =
|
|
2845
|
-
const prevMessageCountRef =
|
|
2846
|
-
const scrollHeightBeforePrependRef =
|
|
2847
|
-
const firstMessageIdRef =
|
|
2848
|
-
const getDistanceFromBottom =
|
|
2861
|
+
const scrollRef = React.useRef(null);
|
|
2862
|
+
const isNearBottomRef = React.useRef(true);
|
|
2863
|
+
const [showScrollBtn, setShowScrollBtn] = React.useState(false);
|
|
2864
|
+
const prevMessageCountRef = React.useRef(messages.length);
|
|
2865
|
+
const scrollHeightBeforePrependRef = React.useRef(null);
|
|
2866
|
+
const firstMessageIdRef = React.useRef(messages[0]?.id);
|
|
2867
|
+
const getDistanceFromBottom = React.useCallback(() => {
|
|
2849
2868
|
const el = scrollRef.current;
|
|
2850
2869
|
if (!el) return 0;
|
|
2851
2870
|
return el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
2852
2871
|
}, []);
|
|
2853
|
-
const scrollToBottom =
|
|
2872
|
+
const scrollToBottom = React.useCallback((behavior = "smooth") => {
|
|
2854
2873
|
const el = scrollRef.current;
|
|
2855
2874
|
if (!el) return;
|
|
2856
2875
|
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
2857
2876
|
}, []);
|
|
2858
|
-
const handleScroll =
|
|
2877
|
+
const handleScroll = React.useCallback(() => {
|
|
2859
2878
|
const el = scrollRef.current;
|
|
2860
2879
|
if (!el) return;
|
|
2861
2880
|
const distance = getDistanceFromBottom();
|
|
@@ -2867,7 +2886,7 @@ function MessageList({
|
|
|
2867
2886
|
onLoadMoreMessages();
|
|
2868
2887
|
}
|
|
2869
2888
|
}, [getDistanceFromBottom, hasMoreMessages, isLoadingMoreMessages, onLoadMoreMessages]);
|
|
2870
|
-
|
|
2889
|
+
React.useLayoutEffect(() => {
|
|
2871
2890
|
const el = scrollRef.current;
|
|
2872
2891
|
const prevHeight = scrollHeightBeforePrependRef.current;
|
|
2873
2892
|
const newFirstId = messages[0]?.id;
|
|
@@ -2877,25 +2896,25 @@ function MessageList({
|
|
|
2877
2896
|
}
|
|
2878
2897
|
firstMessageIdRef.current = newFirstId;
|
|
2879
2898
|
}, [messages]);
|
|
2880
|
-
|
|
2899
|
+
React.useEffect(() => {
|
|
2881
2900
|
const prevCount = prevMessageCountRef.current;
|
|
2882
2901
|
prevMessageCountRef.current = messages.length;
|
|
2883
2902
|
if (messages.length > prevCount && isNearBottomRef.current) {
|
|
2884
2903
|
requestAnimationFrame(() => scrollToBottom());
|
|
2885
2904
|
}
|
|
2886
2905
|
}, [messages.length, scrollToBottom]);
|
|
2887
|
-
|
|
2906
|
+
React.useEffect(() => {
|
|
2888
2907
|
const lastMsg = messages[messages.length - 1];
|
|
2889
2908
|
if (!lastMsg?.isStreaming) return;
|
|
2890
2909
|
if (!isNearBottomRef.current) return;
|
|
2891
2910
|
requestAnimationFrame(() => scrollToBottom());
|
|
2892
2911
|
});
|
|
2893
|
-
|
|
2912
|
+
React.useEffect(() => {
|
|
2894
2913
|
if (messages.length > 0) {
|
|
2895
2914
|
setTimeout(() => scrollToBottom("instant"), 50);
|
|
2896
2915
|
}
|
|
2897
2916
|
}, []);
|
|
2898
|
-
|
|
2917
|
+
React.useEffect(() => {
|
|
2899
2918
|
const handleStepsToggle = () => {
|
|
2900
2919
|
requestAnimationFrame(() => {
|
|
2901
2920
|
requestAnimationFrame(() => {
|
|
@@ -2912,7 +2931,7 @@ function MessageList({
|
|
|
2912
2931
|
return () => el.removeEventListener("payman-steps-toggle", handleStepsToggle);
|
|
2913
2932
|
}
|
|
2914
2933
|
}, [getDistanceFromBottom, scrollToBottom]);
|
|
2915
|
-
const handleScrollToBottom =
|
|
2934
|
+
const handleScrollToBottom = React.useCallback(() => {
|
|
2916
2935
|
scrollToBottom();
|
|
2917
2936
|
}, [scrollToBottom]);
|
|
2918
2937
|
if (isLoading) {
|
|
@@ -3045,7 +3064,7 @@ function ResetSessionConfirmModal({
|
|
|
3045
3064
|
onClose,
|
|
3046
3065
|
onConfirm
|
|
3047
3066
|
}) {
|
|
3048
|
-
const handleKeyDown =
|
|
3067
|
+
const handleKeyDown = React.useCallback(
|
|
3049
3068
|
(event) => {
|
|
3050
3069
|
if (event.key === "Escape") {
|
|
3051
3070
|
onClose();
|
|
@@ -3053,7 +3072,7 @@ function ResetSessionConfirmModal({
|
|
|
3053
3072
|
},
|
|
3054
3073
|
[onClose]
|
|
3055
3074
|
);
|
|
3056
|
-
|
|
3075
|
+
React.useEffect(() => {
|
|
3057
3076
|
if (!isOpen || typeof document === "undefined") return;
|
|
3058
3077
|
document.addEventListener("keydown", handleKeyDown);
|
|
3059
3078
|
const previousOverflow = document.body.style.overflow;
|
|
@@ -3159,14 +3178,14 @@ function UserMessageV2({
|
|
|
3159
3178
|
retryDisabled = false,
|
|
3160
3179
|
actions
|
|
3161
3180
|
}) {
|
|
3162
|
-
const [copied, setCopied] =
|
|
3163
|
-
const [toast, setToast] =
|
|
3164
|
-
const copyResetTimerRef =
|
|
3165
|
-
const toastTimerRef =
|
|
3181
|
+
const [copied, setCopied] = React.useState(false);
|
|
3182
|
+
const [toast, setToast] = React.useState(null);
|
|
3183
|
+
const copyResetTimerRef = React.useRef(null);
|
|
3184
|
+
const toastTimerRef = React.useRef(null);
|
|
3166
3185
|
const showCopyAction = actions?.copy ?? true;
|
|
3167
3186
|
const showEditAction = actions?.edit ?? false;
|
|
3168
3187
|
const showRetryAction = actions?.retry ?? false;
|
|
3169
|
-
|
|
3188
|
+
React.useEffect(() => {
|
|
3170
3189
|
return () => {
|
|
3171
3190
|
if (copyResetTimerRef.current) clearTimeout(copyResetTimerRef.current);
|
|
3172
3191
|
if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
|
|
@@ -3322,18 +3341,18 @@ function MarkdownImageV2({
|
|
|
3322
3341
|
onImageClick
|
|
3323
3342
|
}) {
|
|
3324
3343
|
const cachedAlready = src ? loadedImageCache.has(src) : false;
|
|
3325
|
-
const [isVisible, setIsVisible] =
|
|
3326
|
-
const [isLoaded, setIsLoaded] =
|
|
3327
|
-
const [hasError, setHasError] =
|
|
3328
|
-
const [retryCount, setRetryCount] =
|
|
3329
|
-
const sentinelRef =
|
|
3330
|
-
const prevLoadedRef =
|
|
3331
|
-
const isUnresolvedRag =
|
|
3344
|
+
const [isVisible, setIsVisible] = React.useState(cachedAlready);
|
|
3345
|
+
const [isLoaded, setIsLoaded] = React.useState(cachedAlready);
|
|
3346
|
+
const [hasError, setHasError] = React.useState(false);
|
|
3347
|
+
const [retryCount, setRetryCount] = React.useState(0);
|
|
3348
|
+
const sentinelRef = React.useRef(null);
|
|
3349
|
+
const prevLoadedRef = React.useRef(cachedAlready);
|
|
3350
|
+
const isUnresolvedRag = React.useMemo(
|
|
3332
3351
|
() => src ? isUnresolvedRagImageSource2(src) : false,
|
|
3333
3352
|
[src]
|
|
3334
3353
|
);
|
|
3335
3354
|
const isResolvingRag = Boolean(isResolving && isUnresolvedRag);
|
|
3336
|
-
|
|
3355
|
+
React.useEffect(() => {
|
|
3337
3356
|
if (src && loadedImageCache.has(src)) {
|
|
3338
3357
|
setIsLoaded(true);
|
|
3339
3358
|
setIsVisible(true);
|
|
@@ -3342,7 +3361,7 @@ function MarkdownImageV2({
|
|
|
3342
3361
|
setHasError(false);
|
|
3343
3362
|
setRetryCount(0);
|
|
3344
3363
|
}, [src]);
|
|
3345
|
-
|
|
3364
|
+
React.useEffect(() => {
|
|
3346
3365
|
const el = sentinelRef.current;
|
|
3347
3366
|
if (!el || !src) return;
|
|
3348
3367
|
const rect = el.getBoundingClientRect();
|
|
@@ -3463,9 +3482,88 @@ function MarkdownImageV2({
|
|
|
3463
3482
|
}
|
|
3464
3483
|
) });
|
|
3465
3484
|
}
|
|
3466
|
-
|
|
3485
|
+
var RAG_SOURCE_CLASS = "payman-v2-rag-source";
|
|
3486
|
+
var RAG_FOLLOW_UP_CLASS = "payman-v2-rag-follow-up";
|
|
3487
|
+
var SOURCE_PATTERN = /^Sources?:\s*\S/i;
|
|
3488
|
+
var MAX_FOLLOW_UP_LENGTH = 320;
|
|
3489
|
+
var HR_PATTERN = /^-{3,}$|^_{3,}$|^\*{3,}$/;
|
|
3490
|
+
function normalizeRagParagraphText(text) {
|
|
3491
|
+
return text.replace(/\s+/g, " ").trim();
|
|
3492
|
+
}
|
|
3493
|
+
function isRagSourceParagraph(text) {
|
|
3494
|
+
return SOURCE_PATTERN.test(normalizeRagParagraphText(text));
|
|
3495
|
+
}
|
|
3496
|
+
function isRagFollowUpCandidate(text) {
|
|
3497
|
+
const normalized = normalizeRagParagraphText(text);
|
|
3498
|
+
return normalized.length > 0 && normalized.length <= MAX_FOLLOW_UP_LENGTH && normalized.endsWith("?");
|
|
3499
|
+
}
|
|
3500
|
+
function extractRagParagraphTexts(content) {
|
|
3501
|
+
const paragraphs = [];
|
|
3502
|
+
const currentParagraph = [];
|
|
3503
|
+
const flushParagraph = () => {
|
|
3504
|
+
const paragraph = normalizeRagParagraphText(currentParagraph.join(" "));
|
|
3505
|
+
currentParagraph.length = 0;
|
|
3506
|
+
if (paragraph) paragraphs.push(paragraph);
|
|
3507
|
+
};
|
|
3508
|
+
content.replace(/\\n/g, "\n").split(/\r?\n/).forEach((line) => {
|
|
3509
|
+
const trimmedLine = line.trim();
|
|
3510
|
+
if (!trimmedLine) {
|
|
3511
|
+
flushParagraph();
|
|
3512
|
+
return;
|
|
3513
|
+
}
|
|
3514
|
+
if (HR_PATTERN.test(trimmedLine)) {
|
|
3515
|
+
flushParagraph();
|
|
3516
|
+
return;
|
|
3517
|
+
}
|
|
3518
|
+
currentParagraph.push(trimmedLine);
|
|
3519
|
+
});
|
|
3520
|
+
flushParagraph();
|
|
3521
|
+
return paragraphs;
|
|
3522
|
+
}
|
|
3523
|
+
function getRagAnswerParagraphRoles(paragraphs) {
|
|
3524
|
+
const normalized = paragraphs.map(normalizeRagParagraphText);
|
|
3525
|
+
const roles = normalized.map(() => null);
|
|
3526
|
+
const sourceIndexes = normalized.map((paragraph, index) => isRagSourceParagraph(paragraph) ? index : -1).filter((index) => index >= 0);
|
|
3527
|
+
for (const sourceIndex of sourceIndexes) {
|
|
3528
|
+
roles[sourceIndex] = "source";
|
|
3529
|
+
for (const candidateIndex of [sourceIndex - 1, sourceIndex + 1]) {
|
|
3530
|
+
if (candidateIndex >= 0 && candidateIndex < normalized.length && roles[candidateIndex] == null && isRagFollowUpCandidate(normalized[candidateIndex] ?? "")) {
|
|
3531
|
+
roles[candidateIndex] = "follow-up";
|
|
3532
|
+
}
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3535
|
+
return roles;
|
|
3536
|
+
}
|
|
3537
|
+
function getRagAnswerParagraphRole(paragraph, paragraphs) {
|
|
3538
|
+
const normalizedParagraph = normalizeRagParagraphText(paragraph);
|
|
3539
|
+
if (isRagSourceParagraph(normalizedParagraph)) return "source";
|
|
3540
|
+
const roles = getRagAnswerParagraphRoles(paragraphs);
|
|
3541
|
+
return paragraphs.map(normalizeRagParagraphText).some((candidate, index) => {
|
|
3542
|
+
return candidate === normalizedParagraph && roles[index] === "follow-up";
|
|
3543
|
+
}) ? "follow-up" : null;
|
|
3544
|
+
}
|
|
3545
|
+
function ragAnswerRoleClassName(role) {
|
|
3546
|
+
if (role === "source") return RAG_SOURCE_CLASS;
|
|
3547
|
+
if (role === "follow-up") return RAG_FOLLOW_UP_CLASS;
|
|
3548
|
+
return void 0;
|
|
3549
|
+
}
|
|
3550
|
+
function reactNodeText(node) {
|
|
3551
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
3552
|
+
if (Array.isArray(node)) return node.map(reactNodeText).join("");
|
|
3553
|
+
if (React__namespace.isValidElement(node)) {
|
|
3554
|
+
return reactNodeText(node.props.children);
|
|
3555
|
+
}
|
|
3556
|
+
return "";
|
|
3557
|
+
}
|
|
3558
|
+
function buildComponents(onImageClick, isResolvingRef, ragParagraphsRef) {
|
|
3467
3559
|
return {
|
|
3468
|
-
p: ({ children }) =>
|
|
3560
|
+
p: ({ children }) => {
|
|
3561
|
+
const role = getRagAnswerParagraphRole(
|
|
3562
|
+
reactNodeText(children),
|
|
3563
|
+
ragParagraphsRef?.current ?? []
|
|
3564
|
+
);
|
|
3565
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: ragAnswerRoleClassName(role), children });
|
|
3566
|
+
},
|
|
3469
3567
|
code: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("code", { children }),
|
|
3470
3568
|
pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-markdown-pre", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { children }) }),
|
|
3471
3569
|
ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { children }),
|
|
@@ -3501,10 +3599,15 @@ function MarkdownRendererV2({
|
|
|
3501
3599
|
isResolvingImages,
|
|
3502
3600
|
onImageClick
|
|
3503
3601
|
}) {
|
|
3504
|
-
const isResolvingRef =
|
|
3602
|
+
const isResolvingRef = React.useRef(isResolvingImages);
|
|
3505
3603
|
isResolvingRef.current = isResolvingImages;
|
|
3506
|
-
const
|
|
3507
|
-
|
|
3604
|
+
const ragParagraphsRef = React.useRef([]);
|
|
3605
|
+
ragParagraphsRef.current = React.useMemo(
|
|
3606
|
+
() => extractRagParagraphTexts(content),
|
|
3607
|
+
[content]
|
|
3608
|
+
);
|
|
3609
|
+
const components = React.useMemo(
|
|
3610
|
+
() => buildComponents(onImageClick, isResolvingRef, ragParagraphsRef),
|
|
3508
3611
|
[onImageClick]
|
|
3509
3612
|
);
|
|
3510
3613
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3561,14 +3664,14 @@ function FeedbackReasonModal({
|
|
|
3561
3664
|
onClose,
|
|
3562
3665
|
onSubmit
|
|
3563
3666
|
}) {
|
|
3564
|
-
const [reason, setReason] =
|
|
3667
|
+
const [reason, setReason] = React.useState(
|
|
3565
3668
|
NEGATIVE_FEEDBACK_REASONS[0].value
|
|
3566
3669
|
);
|
|
3567
|
-
const [details, setDetails] =
|
|
3568
|
-
const [submitting, setSubmitting] =
|
|
3569
|
-
const [error, setError] =
|
|
3570
|
-
const [reasonOpen, setReasonOpen] =
|
|
3571
|
-
|
|
3670
|
+
const [details, setDetails] = React.useState("");
|
|
3671
|
+
const [submitting, setSubmitting] = React.useState(false);
|
|
3672
|
+
const [error, setError] = React.useState(null);
|
|
3673
|
+
const [reasonOpen, setReasonOpen] = React.useState(false);
|
|
3674
|
+
React.useEffect(() => {
|
|
3572
3675
|
if (open) {
|
|
3573
3676
|
setReason(NEGATIVE_FEEDBACK_REASONS[0].value);
|
|
3574
3677
|
setDetails("");
|
|
@@ -3577,7 +3680,7 @@ function FeedbackReasonModal({
|
|
|
3577
3680
|
setReasonOpen(false);
|
|
3578
3681
|
}
|
|
3579
3682
|
}, [open]);
|
|
3580
|
-
const handleKeyDown =
|
|
3683
|
+
const handleKeyDown = React.useCallback(
|
|
3581
3684
|
(event) => {
|
|
3582
3685
|
if (event.key !== "Escape") return;
|
|
3583
3686
|
if (reasonOpen) {
|
|
@@ -3588,7 +3691,7 @@ function FeedbackReasonModal({
|
|
|
3588
3691
|
},
|
|
3589
3692
|
[onClose, reasonOpen]
|
|
3590
3693
|
);
|
|
3591
|
-
|
|
3694
|
+
React.useEffect(() => {
|
|
3592
3695
|
if (!open || typeof document === "undefined") return;
|
|
3593
3696
|
document.addEventListener("keydown", handleKeyDown);
|
|
3594
3697
|
const previousOverflow = document.body.style.overflow;
|
|
@@ -3872,17 +3975,17 @@ function charDelay(char, speed, multiplier) {
|
|
|
3872
3975
|
function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDisplayedText, speedMultiplier = 1) {
|
|
3873
3976
|
const instant = speedMultiplier === 0;
|
|
3874
3977
|
const multiplier = instant ? 1 : Math.max(speedMultiplier, 0.1);
|
|
3875
|
-
const [displayedText, setDisplayedText] =
|
|
3876
|
-
const displayedRef =
|
|
3877
|
-
const targetRef =
|
|
3878
|
-
const enabledRef =
|
|
3879
|
-
const initialDisplayedRef =
|
|
3880
|
-
const timerRef =
|
|
3881
|
-
const runningRef =
|
|
3978
|
+
const [displayedText, setDisplayedText] = React.useState("");
|
|
3979
|
+
const displayedRef = React.useRef("");
|
|
3980
|
+
const targetRef = React.useRef(targetText);
|
|
3981
|
+
const enabledRef = React.useRef(enabled);
|
|
3982
|
+
const initialDisplayedRef = React.useRef(initialDisplayedText);
|
|
3983
|
+
const timerRef = React.useRef(null);
|
|
3984
|
+
const runningRef = React.useRef(false);
|
|
3882
3985
|
targetRef.current = targetText;
|
|
3883
3986
|
enabledRef.current = enabled;
|
|
3884
3987
|
initialDisplayedRef.current = initialDisplayedText;
|
|
3885
|
-
|
|
3988
|
+
React.useEffect(() => {
|
|
3886
3989
|
if (!enabled || instant) {
|
|
3887
3990
|
if (timerRef.current) {
|
|
3888
3991
|
clearTimeout(timerRef.current);
|
|
@@ -3965,26 +4068,26 @@ function AssistantMessageV2({
|
|
|
3965
4068
|
actions,
|
|
3966
4069
|
typingSpeed = 4
|
|
3967
4070
|
}) {
|
|
3968
|
-
const [copied, setCopied] =
|
|
3969
|
-
const [activeFeedback, setActiveFeedback] =
|
|
4071
|
+
const [copied, setCopied] = React.useState(false);
|
|
4072
|
+
const [activeFeedback, setActiveFeedback] = React.useState(
|
|
3970
4073
|
() => getFeedbackState(message)
|
|
3971
4074
|
);
|
|
3972
|
-
const [reasonModalOpen, setReasonModalOpen] =
|
|
4075
|
+
const [reasonModalOpen, setReasonModalOpen] = React.useState(false);
|
|
3973
4076
|
const canSubmitFeedback = !!onSubmitFeedback && !!message.executionId;
|
|
3974
|
-
const [toast, setToast] =
|
|
3975
|
-
const copyResetTimerRef =
|
|
3976
|
-
const toastTimerRef =
|
|
4077
|
+
const [toast, setToast] = React.useState(null);
|
|
4078
|
+
const copyResetTimerRef = React.useRef(null);
|
|
4079
|
+
const toastTimerRef = React.useRef(null);
|
|
3977
4080
|
const showCopyAction = actions?.copy ?? true;
|
|
3978
4081
|
const showTraceAction = (actions?.trace ?? true) && !!onExecutionTraceClick;
|
|
3979
4082
|
const showThumbsUp = actions?.thumbsUp ?? true;
|
|
3980
4083
|
const showThumbsDown = actions?.thumbsDown ?? true;
|
|
3981
4084
|
const hydratedFeedback = message.feedback;
|
|
3982
|
-
const hasEverStreamed =
|
|
4085
|
+
const hasEverStreamed = React.useRef(!!message.isStreaming);
|
|
3983
4086
|
if (message.isStreaming) hasEverStreamed.current = true;
|
|
3984
|
-
|
|
4087
|
+
React.useEffect(() => {
|
|
3985
4088
|
setActiveFeedback(getFeedbackState(message));
|
|
3986
4089
|
}, [hydratedFeedback, message.id]);
|
|
3987
|
-
|
|
4090
|
+
React.useEffect(() => {
|
|
3988
4091
|
return () => {
|
|
3989
4092
|
if (copyResetTimerRef.current) clearTimeout(copyResetTimerRef.current);
|
|
3990
4093
|
if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
|
|
@@ -3997,6 +4100,7 @@ function AssistantMessageV2({
|
|
|
3997
4100
|
return message.isStreaming ? stripIncompleteImageToken(normalized) : normalized;
|
|
3998
4101
|
})();
|
|
3999
4102
|
const isThinkingStreaming = !!message.isStreaming && !rawResponseContent && !message.isError;
|
|
4103
|
+
const showTrailingProgress = !!message.isStreaming && !!rawResponseContent && !message.isError && !message.isCancelled && !!message.hasTrailingActivity;
|
|
4000
4104
|
const responseTypingEnabled = hasEverStreamed.current && Boolean(rawResponseContent) && !message.isError;
|
|
4001
4105
|
const { displayedText: displayContent, isTyping: isResponseTyping } = useTypingEffect(
|
|
4002
4106
|
rawResponseContent,
|
|
@@ -4155,7 +4259,7 @@ function AssistantMessageV2({
|
|
|
4155
4259
|
{
|
|
4156
4260
|
isStreaming: isThinkingStreaming,
|
|
4157
4261
|
stickyLabel,
|
|
4158
|
-
currentStepLabel
|
|
4262
|
+
currentStepLabel: currentStepLabel ?? message.currentMessage
|
|
4159
4263
|
}
|
|
4160
4264
|
)
|
|
4161
4265
|
},
|
|
@@ -4170,6 +4274,27 @@ function AssistantMessageV2({
|
|
|
4170
4274
|
onImageClick
|
|
4171
4275
|
}
|
|
4172
4276
|
) : !isThinkingStreaming ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-assistant-msg-placeholder", children: "..." }) : null }),
|
|
4277
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showTrailingProgress && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4278
|
+
framerMotion.motion.div,
|
|
4279
|
+
{
|
|
4280
|
+
initial: { opacity: 0, height: 0 },
|
|
4281
|
+
animate: { opacity: 1, height: "auto" },
|
|
4282
|
+
exit: { opacity: 0, height: 0 },
|
|
4283
|
+
transition: {
|
|
4284
|
+
duration: 0.32,
|
|
4285
|
+
ease: [0.2, 0, 0, 1]
|
|
4286
|
+
},
|
|
4287
|
+
style: { overflow: "hidden" },
|
|
4288
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4289
|
+
ThinkingBlockV2,
|
|
4290
|
+
{
|
|
4291
|
+
isStreaming: true,
|
|
4292
|
+
currentStepLabel: message.currentMessage ?? currentStepLabel
|
|
4293
|
+
}
|
|
4294
|
+
)
|
|
4295
|
+
},
|
|
4296
|
+
"trailing-progress"
|
|
4297
|
+
) }),
|
|
4173
4298
|
isCancelled && message.isStreaming && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-assistant-msg-paused", children: [
|
|
4174
4299
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4175
4300
|
lucideReact.WifiOff,
|
|
@@ -4278,10 +4403,10 @@ function OtpInputV2({
|
|
|
4278
4403
|
disabled = false,
|
|
4279
4404
|
error = false
|
|
4280
4405
|
}) {
|
|
4281
|
-
const inputRefs =
|
|
4406
|
+
const inputRefs = React.useRef([]);
|
|
4282
4407
|
const safeMaxLength = Number.isInteger(maxLength) && maxLength > 0 ? Math.min(maxLength, MAX_SUPPORTED_LENGTH) : DEFAULT_MAX_LENGTH;
|
|
4283
4408
|
const digits = value.split("").concat(Array(safeMaxLength).fill("")).slice(0, safeMaxLength);
|
|
4284
|
-
|
|
4409
|
+
React.useEffect(() => {
|
|
4285
4410
|
if (disabled) return;
|
|
4286
4411
|
const timer = window.setTimeout(() => {
|
|
4287
4412
|
inputRefs.current[0]?.focus();
|
|
@@ -4380,31 +4505,31 @@ function VerificationInline({
|
|
|
4380
4505
|
onResend
|
|
4381
4506
|
}) {
|
|
4382
4507
|
const isNumeric = prompt.verificationType !== "ALPHANUMERIC_CODE";
|
|
4383
|
-
const codeLen =
|
|
4384
|
-
const [code, setCode] =
|
|
4385
|
-
const [errored, setErrored] =
|
|
4386
|
-
const [resendSec, setResendSec] =
|
|
4387
|
-
const [hiddenAfterResend, setHiddenAfterResend] =
|
|
4388
|
-
const lastSubmittedRef =
|
|
4389
|
-
const resendTimerRef =
|
|
4508
|
+
const codeLen = React.useMemo(() => codeLengthFromSchema(prompt), [prompt]);
|
|
4509
|
+
const [code, setCode] = React.useState("");
|
|
4510
|
+
const [errored, setErrored] = React.useState(false);
|
|
4511
|
+
const [resendSec, setResendSec] = React.useState(0);
|
|
4512
|
+
const [hiddenAfterResend, setHiddenAfterResend] = React.useState(false);
|
|
4513
|
+
const lastSubmittedRef = React.useRef(null);
|
|
4514
|
+
const resendTimerRef = React.useRef(void 0);
|
|
4390
4515
|
const status = prompt.status;
|
|
4391
4516
|
const busy = status === "submitting";
|
|
4392
4517
|
const stale = status === "stale";
|
|
4393
4518
|
const locked = busy || stale || expired;
|
|
4394
|
-
|
|
4519
|
+
React.useEffect(() => {
|
|
4395
4520
|
if (prompt.subAction === "SubmissionInvalid") {
|
|
4396
4521
|
setErrored(true);
|
|
4397
4522
|
setCode("");
|
|
4398
4523
|
lastSubmittedRef.current = null;
|
|
4399
4524
|
}
|
|
4400
4525
|
}, [prompt.subAction, prompt.userActionId]);
|
|
4401
|
-
|
|
4526
|
+
React.useEffect(() => {
|
|
4402
4527
|
setHiddenAfterResend(false);
|
|
4403
4528
|
}, [prompt.expirySeconds, prompt.message, prompt.subAction, prompt.userActionId]);
|
|
4404
|
-
|
|
4529
|
+
React.useEffect(() => {
|
|
4405
4530
|
if (code.length < codeLen) lastSubmittedRef.current = null;
|
|
4406
4531
|
}, [code, codeLen]);
|
|
4407
|
-
const doSubmit =
|
|
4532
|
+
const doSubmit = React.useCallback(
|
|
4408
4533
|
(value) => {
|
|
4409
4534
|
if (locked || !value) return;
|
|
4410
4535
|
if (lastSubmittedRef.current === value) return;
|
|
@@ -4416,20 +4541,20 @@ function VerificationInline({
|
|
|
4416
4541
|
},
|
|
4417
4542
|
[locked, onSubmit, prompt.userActionId]
|
|
4418
4543
|
);
|
|
4419
|
-
|
|
4544
|
+
React.useEffect(() => {
|
|
4420
4545
|
if (!isNumeric || locked) return;
|
|
4421
4546
|
if (code.length === codeLen && /^\d+$/.test(code)) {
|
|
4422
4547
|
doSubmit(code);
|
|
4423
4548
|
}
|
|
4424
4549
|
}, [code, codeLen, doSubmit, isNumeric, locked]);
|
|
4425
|
-
|
|
4550
|
+
React.useEffect(() => {
|
|
4426
4551
|
return () => {
|
|
4427
4552
|
if (typeof resendTimerRef.current === "number") {
|
|
4428
4553
|
window.clearInterval(resendTimerRef.current);
|
|
4429
4554
|
}
|
|
4430
4555
|
};
|
|
4431
4556
|
}, []);
|
|
4432
|
-
const startResendCooldown =
|
|
4557
|
+
const startResendCooldown = React.useCallback(() => {
|
|
4433
4558
|
setResendSec(RESEND_COOLDOWN_S);
|
|
4434
4559
|
if (typeof resendTimerRef.current === "number") {
|
|
4435
4560
|
window.clearInterval(resendTimerRef.current);
|
|
@@ -4447,7 +4572,7 @@ function VerificationInline({
|
|
|
4447
4572
|
});
|
|
4448
4573
|
}, 1e3);
|
|
4449
4574
|
}, []);
|
|
4450
|
-
const handleResend =
|
|
4575
|
+
const handleResend = React.useCallback(async () => {
|
|
4451
4576
|
if (locked || resendSec > 0) return;
|
|
4452
4577
|
setErrored(false);
|
|
4453
4578
|
setCode("");
|
|
@@ -4460,11 +4585,14 @@ function VerificationInline({
|
|
|
4460
4585
|
setHiddenAfterResend(false);
|
|
4461
4586
|
}
|
|
4462
4587
|
}, [locked, onResend, prompt.userActionId, resendSec, startResendCooldown]);
|
|
4463
|
-
const handleCancel =
|
|
4588
|
+
const handleCancel = React.useCallback(() => {
|
|
4464
4589
|
if (busy) return;
|
|
4465
4590
|
void onCancel(prompt.userActionId);
|
|
4466
4591
|
}, [busy, onCancel, prompt.userActionId]);
|
|
4467
|
-
const
|
|
4592
|
+
const promptMessage = prompt.message?.trim();
|
|
4593
|
+
const description = promptMessage || (isNumeric ? `Enter the ${codeLen}-digit code to continue` : "Enter the verification code to continue");
|
|
4594
|
+
const messageFormat = prompt.metadata?.["payman/messageFormat"];
|
|
4595
|
+
const renderMarkdown = !!promptMessage && messageFormat === "markdown";
|
|
4468
4596
|
if (hiddenAfterResend) return null;
|
|
4469
4597
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-ua", role: "group", "aria-label": "Verification required", children: [
|
|
4470
4598
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-ua-head", children: [
|
|
@@ -4472,7 +4600,7 @@ function VerificationInline({
|
|
|
4472
4600
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-title", children: "Verification required" }),
|
|
4473
4601
|
typeof secondsLeft === "number" && !stale && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-timer", children: expired ? "Expired" : `${secondsLeft}s` })
|
|
4474
4602
|
] }),
|
|
4475
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-desc", children: description }),
|
|
4603
|
+
renderMarkdown ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-ua-markdown", children: /* @__PURE__ */ jsxRuntime.jsx(MarkdownRendererV2, { content: description }) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-desc", children: description }),
|
|
4476
4604
|
stale ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-stale", children: "This request is no longer available." }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4477
4605
|
isNumeric ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-ua-field", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4478
4606
|
OtpInputV2,
|
|
@@ -4550,13 +4678,13 @@ function SchemaFormInline({
|
|
|
4550
4678
|
onCancel
|
|
4551
4679
|
}) {
|
|
4552
4680
|
const schema = prompt.requestedSchema;
|
|
4553
|
-
const fields =
|
|
4554
|
-
const [values, setValues] =
|
|
4681
|
+
const fields = React.useMemo(() => renderableFields(schema), [schema]);
|
|
4682
|
+
const [values, setValues] = React.useState(() => {
|
|
4555
4683
|
const init2 = {};
|
|
4556
4684
|
for (const [key, field] of fields) init2[key] = defaultValueFor(field);
|
|
4557
4685
|
return init2;
|
|
4558
4686
|
});
|
|
4559
|
-
const [errors, setErrors] =
|
|
4687
|
+
const [errors, setErrors] = React.useState({});
|
|
4560
4688
|
const status = prompt.status;
|
|
4561
4689
|
const busy = status === "submitting";
|
|
4562
4690
|
const stale = status === "stale";
|
|
@@ -4697,10 +4825,10 @@ function NotificationInline({ notification, onDismiss }) {
|
|
|
4697
4825
|
}
|
|
4698
4826
|
function useExpiryCountdown(prompt) {
|
|
4699
4827
|
const deadlineMs = typeof prompt.expiresAt === "number" && prompt.expiresAt > 0 ? prompt.expiresAt : typeof prompt.expirySeconds === "number" && prompt.expirySeconds > 0 ? Date.now() + Math.floor(prompt.expirySeconds) * 1e3 : void 0;
|
|
4700
|
-
const [secondsLeft, setSecondsLeft] =
|
|
4828
|
+
const [secondsLeft, setSecondsLeft] = React.useState(
|
|
4701
4829
|
() => deadlineMs !== void 0 ? Math.max(0, Math.ceil((deadlineMs - Date.now()) / 1e3)) : void 0
|
|
4702
4830
|
);
|
|
4703
|
-
|
|
4831
|
+
React.useEffect(() => {
|
|
4704
4832
|
if (deadlineMs === void 0) {
|
|
4705
4833
|
setSecondsLeft(void 0);
|
|
4706
4834
|
return;
|
|
@@ -4738,7 +4866,7 @@ function UserActionInline({
|
|
|
4738
4866
|
onExpired
|
|
4739
4867
|
}) {
|
|
4740
4868
|
const [secondsLeft, expired] = useExpiryCountdown(prompt);
|
|
4741
|
-
|
|
4869
|
+
React.useEffect(() => {
|
|
4742
4870
|
if (expired && prompt.kind !== "notification") onExpired?.();
|
|
4743
4871
|
}, [expired, onExpired, prompt.kind]);
|
|
4744
4872
|
let body;
|
|
@@ -4801,7 +4929,7 @@ function getPromptViewKey(prompt) {
|
|
|
4801
4929
|
prompt.message ?? ""
|
|
4802
4930
|
].join(PROMPT_KEY_SEPARATOR);
|
|
4803
4931
|
}
|
|
4804
|
-
var MessageListV2 =
|
|
4932
|
+
var MessageListV2 = React.forwardRef(
|
|
4805
4933
|
function MessageListV22({
|
|
4806
4934
|
messages,
|
|
4807
4935
|
isStreaming = false,
|
|
@@ -4821,25 +4949,25 @@ var MessageListV2 = react.forwardRef(
|
|
|
4821
4949
|
onSubmitFeedback,
|
|
4822
4950
|
typingSpeed = 4
|
|
4823
4951
|
}, ref) {
|
|
4824
|
-
const noop =
|
|
4952
|
+
const noop = React.useCallback(async () => {
|
|
4825
4953
|
}, []);
|
|
4826
|
-
const scrollRef =
|
|
4827
|
-
const scrollInnerRef =
|
|
4828
|
-
const isNearBottomRef =
|
|
4829
|
-
const [showScrollBtn, setShowScrollBtn] =
|
|
4830
|
-
const [expiredPromptViewState, setExpiredPromptViewState] =
|
|
4831
|
-
const expiredUserActionIdsRef =
|
|
4832
|
-
const prevCountRef =
|
|
4833
|
-
const pauseStickUntilUserMessageRef =
|
|
4834
|
-
const followingBottomRef =
|
|
4835
|
-
const lastPinAtRef =
|
|
4836
|
-
const prevScrollTopRef =
|
|
4837
|
-
const getDistanceFromBottom =
|
|
4954
|
+
const scrollRef = React.useRef(null);
|
|
4955
|
+
const scrollInnerRef = React.useRef(null);
|
|
4956
|
+
const isNearBottomRef = React.useRef(true);
|
|
4957
|
+
const [showScrollBtn, setShowScrollBtn] = React.useState(false);
|
|
4958
|
+
const [expiredPromptViewState, setExpiredPromptViewState] = React.useState({});
|
|
4959
|
+
const expiredUserActionIdsRef = React.useRef(/* @__PURE__ */ new Set());
|
|
4960
|
+
const prevCountRef = React.useRef(messages.length);
|
|
4961
|
+
const pauseStickUntilUserMessageRef = React.useRef(false);
|
|
4962
|
+
const followingBottomRef = React.useRef(true);
|
|
4963
|
+
const lastPinAtRef = React.useRef(0);
|
|
4964
|
+
const prevScrollTopRef = React.useRef(0);
|
|
4965
|
+
const getDistanceFromBottom = React.useCallback(() => {
|
|
4838
4966
|
const el = scrollRef.current;
|
|
4839
4967
|
if (!el) return 0;
|
|
4840
4968
|
return el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
4841
4969
|
}, []);
|
|
4842
|
-
const messageActivityFingerprint =
|
|
4970
|
+
const messageActivityFingerprint = React.useMemo(() => {
|
|
4843
4971
|
const last = messages[messages.length - 1];
|
|
4844
4972
|
const promptFingerprint = (userActionPrompts ?? []).map((prompt) => `${getPromptViewKey(prompt)}:${prompt.status}`).join(PROMPT_KEY_SEPARATOR);
|
|
4845
4973
|
const notificationFingerprint = (notifications ?? []).map((notification) => notification.id).join(PROMPT_KEY_SEPARATOR);
|
|
@@ -4865,7 +4993,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4865
4993
|
notificationFingerprint
|
|
4866
4994
|
].join(PROMPT_KEY_SEPARATOR);
|
|
4867
4995
|
}, [isStreaming, messages, notifications, userActionPrompts]);
|
|
4868
|
-
const handleUserActionExpired =
|
|
4996
|
+
const handleUserActionExpired = React.useCallback(
|
|
4869
4997
|
(promptKey, userActionId) => {
|
|
4870
4998
|
setExpiredPromptViewState((prev) => {
|
|
4871
4999
|
if (prev[promptKey]) return prev;
|
|
@@ -4882,7 +5010,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4882
5010
|
},
|
|
4883
5011
|
[messageActivityFingerprint, onExpireUserAction]
|
|
4884
5012
|
);
|
|
4885
|
-
|
|
5013
|
+
React.useEffect(() => {
|
|
4886
5014
|
setExpiredPromptViewState((prev) => {
|
|
4887
5015
|
let changed = false;
|
|
4888
5016
|
const next = {};
|
|
@@ -4897,7 +5025,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4897
5025
|
return changed ? next : prev;
|
|
4898
5026
|
});
|
|
4899
5027
|
}, [messageActivityFingerprint]);
|
|
4900
|
-
|
|
5028
|
+
React.useEffect(() => {
|
|
4901
5029
|
const livePromptKeys = new Set((userActionPrompts ?? []).map(getPromptViewKey));
|
|
4902
5030
|
const liveUserActionIds = new Set((userActionPrompts ?? []).map((p) => p.userActionId));
|
|
4903
5031
|
for (const userActionId of expiredUserActionIdsRef.current) {
|
|
@@ -4918,21 +5046,21 @@ var MessageListV2 = react.forwardRef(
|
|
|
4918
5046
|
return changed ? next : prev;
|
|
4919
5047
|
});
|
|
4920
5048
|
}, [userActionPrompts]);
|
|
4921
|
-
const visibleUserActionPrompts =
|
|
5049
|
+
const visibleUserActionPrompts = React.useMemo(
|
|
4922
5050
|
() => userActionPrompts?.filter((prompt) => {
|
|
4923
5051
|
const promptKey = getPromptViewKey(prompt);
|
|
4924
5052
|
return !expiredPromptViewState[promptKey]?.hidden;
|
|
4925
5053
|
}),
|
|
4926
5054
|
[expiredPromptViewState, userActionPrompts]
|
|
4927
5055
|
);
|
|
4928
|
-
const pinToBottom =
|
|
5056
|
+
const pinToBottom = React.useCallback((behavior = "instant") => {
|
|
4929
5057
|
const el = scrollRef.current;
|
|
4930
5058
|
if (!el) return;
|
|
4931
5059
|
lastPinAtRef.current = performance.now();
|
|
4932
5060
|
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
4933
5061
|
prevScrollTopRef.current = el.scrollHeight;
|
|
4934
5062
|
}, []);
|
|
4935
|
-
const scrollToBottom =
|
|
5063
|
+
const scrollToBottom = React.useCallback(
|
|
4936
5064
|
(behavior = "smooth") => {
|
|
4937
5065
|
const el = scrollRef.current;
|
|
4938
5066
|
if (!el) return;
|
|
@@ -4942,7 +5070,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4942
5070
|
},
|
|
4943
5071
|
[pinToBottom]
|
|
4944
5072
|
);
|
|
4945
|
-
|
|
5073
|
+
React.useImperativeHandle(
|
|
4946
5074
|
ref,
|
|
4947
5075
|
() => ({
|
|
4948
5076
|
scrollToBottom: (behavior = "smooth") => {
|
|
@@ -4955,7 +5083,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4955
5083
|
}),
|
|
4956
5084
|
[scrollToBottom]
|
|
4957
5085
|
);
|
|
4958
|
-
const handleScroll =
|
|
5086
|
+
const handleScroll = React.useCallback(() => {
|
|
4959
5087
|
const el = scrollRef.current;
|
|
4960
5088
|
if (!el) return;
|
|
4961
5089
|
const currentScrollTop = el.scrollTop;
|
|
@@ -4976,7 +5104,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4976
5104
|
pauseStickUntilUserMessageRef.current = false;
|
|
4977
5105
|
}
|
|
4978
5106
|
}, [getDistanceFromBottom]);
|
|
4979
|
-
|
|
5107
|
+
React.useEffect(() => {
|
|
4980
5108
|
const prevCount = prevCountRef.current;
|
|
4981
5109
|
prevCountRef.current = messages.length;
|
|
4982
5110
|
if (messages.length > prevCount) {
|
|
@@ -4990,7 +5118,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
4990
5118
|
}
|
|
4991
5119
|
}
|
|
4992
5120
|
}, [messages.length, scrollToBottom]);
|
|
4993
|
-
|
|
5121
|
+
React.useEffect(() => {
|
|
4994
5122
|
const inner = scrollInnerRef.current;
|
|
4995
5123
|
if (!inner) return;
|
|
4996
5124
|
const pinIfFollowing = () => {
|
|
@@ -5015,7 +5143,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
5015
5143
|
mo.disconnect();
|
|
5016
5144
|
};
|
|
5017
5145
|
}, [pinToBottom]);
|
|
5018
|
-
|
|
5146
|
+
React.useEffect(() => {
|
|
5019
5147
|
if (messages.length > 0) {
|
|
5020
5148
|
setTimeout(() => scrollToBottom("instant"), 50);
|
|
5021
5149
|
}
|
|
@@ -5104,7 +5232,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
5104
5232
|
] });
|
|
5105
5233
|
}
|
|
5106
5234
|
);
|
|
5107
|
-
var ChatInputV2 =
|
|
5235
|
+
var ChatInputV2 = React.forwardRef(
|
|
5108
5236
|
function ChatInputV22({
|
|
5109
5237
|
onSend,
|
|
5110
5238
|
disabled = false,
|
|
@@ -5128,20 +5256,20 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5128
5256
|
onAnalysisModeChange,
|
|
5129
5257
|
slashCommands = []
|
|
5130
5258
|
}, ref) {
|
|
5131
|
-
const [value, setValue] =
|
|
5132
|
-
const [isFocused, setIsFocused] =
|
|
5133
|
-
const [showActions, setShowActions] =
|
|
5134
|
-
const [showVoiceTooltip, setShowVoiceTooltip] =
|
|
5135
|
-
const [selectedCommandIndex, setSelectedCommandIndex] =
|
|
5136
|
-
const [inlineHint, setInlineHint] =
|
|
5137
|
-
const [commandMenuDismissed, setCommandMenuDismissed] =
|
|
5138
|
-
const textareaRef =
|
|
5139
|
-
const actionsRef =
|
|
5140
|
-
const preRecordTextRef =
|
|
5141
|
-
const voiceTooltipTimerRef =
|
|
5259
|
+
const [value, setValue] = React.useState("");
|
|
5260
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
5261
|
+
const [showActions, setShowActions] = React.useState(false);
|
|
5262
|
+
const [showVoiceTooltip, setShowVoiceTooltip] = React.useState(false);
|
|
5263
|
+
const [selectedCommandIndex, setSelectedCommandIndex] = React.useState(0);
|
|
5264
|
+
const [inlineHint, setInlineHint] = React.useState(null);
|
|
5265
|
+
const [commandMenuDismissed, setCommandMenuDismissed] = React.useState(false);
|
|
5266
|
+
const textareaRef = React.useRef(null);
|
|
5267
|
+
const actionsRef = React.useRef(null);
|
|
5268
|
+
const preRecordTextRef = React.useRef("");
|
|
5269
|
+
const voiceTooltipTimerRef = React.useRef(
|
|
5142
5270
|
null
|
|
5143
5271
|
);
|
|
5144
|
-
const voiceDraftSyncActiveRef =
|
|
5272
|
+
const voiceDraftSyncActiveRef = React.useRef(false);
|
|
5145
5273
|
const isInputLocked = disabled || isRecording;
|
|
5146
5274
|
const hasAttachmentOptions = showUploadImageButton || showAttachFileButton;
|
|
5147
5275
|
const showAttachmentMenuButton = showAttachmentButton && hasAttachmentOptions;
|
|
@@ -5152,14 +5280,14 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5152
5280
|
(command) => command.name.toLowerCase().startsWith(commandQuery)
|
|
5153
5281
|
);
|
|
5154
5282
|
const showCommandSuggestions = !commandMenuDismissed && !isRecording && !disabled && commandSuggestions.length > 0;
|
|
5155
|
-
|
|
5283
|
+
React.useEffect(() => {
|
|
5156
5284
|
if (textareaRef.current) {
|
|
5157
5285
|
textareaRef.current.style.height = "auto";
|
|
5158
5286
|
const scrollHeight = textareaRef.current.scrollHeight;
|
|
5159
5287
|
textareaRef.current.style.height = `${Math.min(scrollHeight, 200)}px`;
|
|
5160
5288
|
}
|
|
5161
5289
|
}, [value]);
|
|
5162
|
-
|
|
5290
|
+
React.useEffect(() => {
|
|
5163
5291
|
if (disabled) {
|
|
5164
5292
|
setIsFocused(false);
|
|
5165
5293
|
setShowActions(false);
|
|
@@ -5169,7 +5297,7 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5169
5297
|
const frameId = requestAnimationFrame(() => textareaRef.current?.focus());
|
|
5170
5298
|
return () => cancelAnimationFrame(frameId);
|
|
5171
5299
|
}, [disabled]);
|
|
5172
|
-
|
|
5300
|
+
React.useImperativeHandle(
|
|
5173
5301
|
ref,
|
|
5174
5302
|
() => ({
|
|
5175
5303
|
setDraft: (message) => {
|
|
@@ -5186,7 +5314,7 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5186
5314
|
}),
|
|
5187
5315
|
[disabled]
|
|
5188
5316
|
);
|
|
5189
|
-
|
|
5317
|
+
React.useEffect(() => {
|
|
5190
5318
|
if (!showActions) return;
|
|
5191
5319
|
const handleClickOutside = (e) => {
|
|
5192
5320
|
if (actionsRef.current && !actionsRef.current.contains(e.target)) {
|
|
@@ -5196,29 +5324,29 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5196
5324
|
document.addEventListener("mousedown", handleClickOutside);
|
|
5197
5325
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
5198
5326
|
}, [showActions]);
|
|
5199
|
-
|
|
5327
|
+
React.useEffect(() => {
|
|
5200
5328
|
if (!showAttachmentMenuButton) {
|
|
5201
5329
|
setShowActions(false);
|
|
5202
5330
|
}
|
|
5203
5331
|
}, [showAttachmentMenuButton]);
|
|
5204
|
-
|
|
5332
|
+
React.useEffect(() => {
|
|
5205
5333
|
setSelectedCommandIndex(0);
|
|
5206
5334
|
setCommandMenuDismissed(false);
|
|
5207
5335
|
}, [commandQuery]);
|
|
5208
|
-
|
|
5336
|
+
React.useEffect(() => {
|
|
5209
5337
|
return () => {
|
|
5210
5338
|
if (voiceTooltipTimerRef.current) {
|
|
5211
5339
|
clearTimeout(voiceTooltipTimerRef.current);
|
|
5212
5340
|
}
|
|
5213
5341
|
};
|
|
5214
5342
|
}, []);
|
|
5215
|
-
|
|
5343
|
+
React.useEffect(() => {
|
|
5216
5344
|
if (!voiceDraftSyncActiveRef.current) return;
|
|
5217
5345
|
const base = preRecordTextRef.current;
|
|
5218
5346
|
const separator = base && !base.endsWith(" ") && transcribedText ? " " : "";
|
|
5219
5347
|
setValue(`${base}${separator}${transcribedText}`);
|
|
5220
5348
|
}, [isRecording, transcribedText]);
|
|
5221
|
-
const handleSend =
|
|
5349
|
+
const handleSend = React.useCallback(() => {
|
|
5222
5350
|
if (!value.trim() || disabled) return;
|
|
5223
5351
|
const commandHint = getSlashCommandValidationHint(value);
|
|
5224
5352
|
if (commandHint) {
|
|
@@ -5238,7 +5366,7 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5238
5366
|
}
|
|
5239
5367
|
});
|
|
5240
5368
|
}, [value, disabled, onClearEditing, onSend]);
|
|
5241
|
-
const selectCommand =
|
|
5369
|
+
const selectCommand = React.useCallback(
|
|
5242
5370
|
(command) => {
|
|
5243
5371
|
const insertText = command.insertText ?? `${command.name} `;
|
|
5244
5372
|
setValue(insertText);
|
|
@@ -5294,14 +5422,14 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5294
5422
|
onAttachFileClick?.();
|
|
5295
5423
|
setShowActions(false);
|
|
5296
5424
|
};
|
|
5297
|
-
const hideVoiceTooltip =
|
|
5425
|
+
const hideVoiceTooltip = React.useCallback(() => {
|
|
5298
5426
|
if (voiceTooltipTimerRef.current) {
|
|
5299
5427
|
clearTimeout(voiceTooltipTimerRef.current);
|
|
5300
5428
|
voiceTooltipTimerRef.current = null;
|
|
5301
5429
|
}
|
|
5302
5430
|
setShowVoiceTooltip(false);
|
|
5303
5431
|
}, []);
|
|
5304
|
-
const startVoiceTooltipTimer =
|
|
5432
|
+
const startVoiceTooltipTimer = React.useCallback(() => {
|
|
5305
5433
|
if (isVoiceButtonDisabled || isRecording) return;
|
|
5306
5434
|
if (voiceTooltipTimerRef.current) {
|
|
5307
5435
|
clearTimeout(voiceTooltipTimerRef.current);
|
|
@@ -5623,9 +5751,9 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5623
5751
|
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=";
|
|
5624
5752
|
var DEFAULT_SIZE = 36;
|
|
5625
5753
|
function useElapsedSeconds(isStreaming) {
|
|
5626
|
-
const [elapsed, setElapsed] =
|
|
5627
|
-
const startRef =
|
|
5628
|
-
|
|
5754
|
+
const [elapsed, setElapsed] = React.useState(0);
|
|
5755
|
+
const startRef = React.useRef(null);
|
|
5756
|
+
React.useEffect(() => {
|
|
5629
5757
|
if (!isStreaming) {
|
|
5630
5758
|
startRef.current = null;
|
|
5631
5759
|
setElapsed(0);
|
|
@@ -5684,22 +5812,22 @@ function StreamingIndicatorV2({
|
|
|
5684
5812
|
) });
|
|
5685
5813
|
}
|
|
5686
5814
|
function ImageLightboxV2({ src, alt, onClose }) {
|
|
5687
|
-
const [isMounted, setIsMounted] =
|
|
5688
|
-
const [isImageLoaded, setIsImageLoaded] =
|
|
5689
|
-
|
|
5815
|
+
const [isMounted, setIsMounted] = React.useState(false);
|
|
5816
|
+
const [isImageLoaded, setIsImageLoaded] = React.useState(false);
|
|
5817
|
+
React.useEffect(() => {
|
|
5690
5818
|
setIsMounted(true);
|
|
5691
5819
|
return () => setIsMounted(false);
|
|
5692
5820
|
}, []);
|
|
5693
|
-
|
|
5821
|
+
React.useEffect(() => {
|
|
5694
5822
|
setIsImageLoaded(false);
|
|
5695
5823
|
}, [src]);
|
|
5696
|
-
const handleKeyDown =
|
|
5824
|
+
const handleKeyDown = React.useCallback(
|
|
5697
5825
|
(e) => {
|
|
5698
5826
|
if (e.key === "Escape") onClose();
|
|
5699
5827
|
},
|
|
5700
5828
|
[onClose]
|
|
5701
5829
|
);
|
|
5702
|
-
|
|
5830
|
+
React.useEffect(() => {
|
|
5703
5831
|
if (!src || typeof document === "undefined") return;
|
|
5704
5832
|
document.addEventListener("keydown", handleKeyDown);
|
|
5705
5833
|
const previousOverflow = document.body.style.overflow;
|
|
@@ -5848,10 +5976,10 @@ function TraceTimelineModal({
|
|
|
5848
5976
|
apiBaseUrl,
|
|
5849
5977
|
apiHeaders
|
|
5850
5978
|
}) {
|
|
5851
|
-
const [trace, setTrace] =
|
|
5852
|
-
const [loading, setLoading] =
|
|
5853
|
-
const [error, setError] =
|
|
5854
|
-
|
|
5979
|
+
const [trace, setTrace] = React.useState(null);
|
|
5980
|
+
const [loading, setLoading] = React.useState(false);
|
|
5981
|
+
const [error, setError] = React.useState(null);
|
|
5982
|
+
React.useEffect(() => {
|
|
5855
5983
|
if (!open || !executionId) return;
|
|
5856
5984
|
const ctrl = new AbortController();
|
|
5857
5985
|
setLoading(true);
|
|
@@ -5873,7 +6001,7 @@ function TraceTimelineModal({
|
|
|
5873
6001
|
}).finally(() => setLoading(false));
|
|
5874
6002
|
return () => ctrl.abort();
|
|
5875
6003
|
}, [open, executionId, apiBaseUrl, apiHeaders]);
|
|
5876
|
-
const totalMs =
|
|
6004
|
+
const totalMs = React.useMemo(() => {
|
|
5877
6005
|
if (!trace) return 0;
|
|
5878
6006
|
const meta = trace.runMetadata?.totalTimeMs;
|
|
5879
6007
|
if (typeof meta === "number" && meta > 0) return meta;
|
|
@@ -5882,7 +6010,7 @@ function TraceTimelineModal({
|
|
|
5882
6010
|
if (starts.length === 0 || ends.length === 0) return 0;
|
|
5883
6011
|
return Math.max(...ends) - Math.min(...starts);
|
|
5884
6012
|
}, [trace]);
|
|
5885
|
-
const accountedMs =
|
|
6013
|
+
const accountedMs = React.useMemo(
|
|
5886
6014
|
() => (trace?.pipelineSteps ?? []).reduce(
|
|
5887
6015
|
(sum, s) => sum + (s.durationMs ?? 0),
|
|
5888
6016
|
0
|
|
@@ -6143,12 +6271,12 @@ var NOOP_ASYNC = async () => {
|
|
|
6143
6271
|
var NOOP = () => {
|
|
6144
6272
|
};
|
|
6145
6273
|
function useSentryChatCallbacks(callbacks, config) {
|
|
6146
|
-
const sentryCtxRef =
|
|
6147
|
-
const callbacksRef =
|
|
6274
|
+
const sentryCtxRef = React.useRef({});
|
|
6275
|
+
const callbacksRef = React.useRef(callbacks);
|
|
6148
6276
|
callbacksRef.current = callbacks;
|
|
6149
6277
|
const initialSessionId = config.initialSessionId;
|
|
6150
6278
|
const apiHeaders = config.api.headers;
|
|
6151
|
-
|
|
6279
|
+
React.useEffect(() => {
|
|
6152
6280
|
sentryCtxRef.current.agentId = config.agentId;
|
|
6153
6281
|
sentryCtxRef.current.sessionOwnerId = config.sessionParams?.id;
|
|
6154
6282
|
if (initialSessionId) {
|
|
@@ -6164,13 +6292,13 @@ function useSentryChatCallbacks(callbacks, config) {
|
|
|
6164
6292
|
initialSessionId,
|
|
6165
6293
|
apiHeaders
|
|
6166
6294
|
]);
|
|
6167
|
-
|
|
6295
|
+
React.useEffect(() => {
|
|
6168
6296
|
const endpoint = config.api.streamEndpoint || "/api/playground/ask/stream";
|
|
6169
6297
|
return subscribeToCfRay(endpoint, (cfRay) => {
|
|
6170
6298
|
sentryCtxRef.current.cfRay = cfRay;
|
|
6171
6299
|
});
|
|
6172
6300
|
}, [config.api.streamEndpoint]);
|
|
6173
|
-
return
|
|
6301
|
+
return React.useMemo(
|
|
6174
6302
|
() => ({
|
|
6175
6303
|
onMessageSent: (msg) => callbacksRef.current?.onMessageSent?.(msg),
|
|
6176
6304
|
onStreamStart: () => callbacksRef.current?.onStreamStart?.(),
|
|
@@ -6219,7 +6347,7 @@ function useSentryChatCallbacks(callbacks, config) {
|
|
|
6219
6347
|
[]
|
|
6220
6348
|
);
|
|
6221
6349
|
}
|
|
6222
|
-
var PaymanChatInner =
|
|
6350
|
+
var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
|
|
6223
6351
|
config,
|
|
6224
6352
|
callbacks = {},
|
|
6225
6353
|
className,
|
|
@@ -6230,18 +6358,18 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6230
6358
|
hasMoreMessages = false,
|
|
6231
6359
|
chat
|
|
6232
6360
|
}, ref) {
|
|
6233
|
-
const [inputValue, setInputValue] =
|
|
6234
|
-
const prevInputValueRef =
|
|
6235
|
-
const [hasEverSentMessage, setHasEverSentMessage] =
|
|
6236
|
-
const [lightboxSrc, setLightboxSrc] =
|
|
6237
|
-
const [lightboxAlt, setLightboxAlt] =
|
|
6238
|
-
const [editingMessageId, setEditingMessageId] =
|
|
6239
|
-
const [isResetSessionConfirmOpen, setIsResetSessionConfirmOpen] =
|
|
6240
|
-
const [analysisMode, setAnalysisMode] =
|
|
6241
|
-
const chatInputV2Ref =
|
|
6242
|
-
const messageListV2Ref =
|
|
6243
|
-
const resetToEmptyStateRef =
|
|
6244
|
-
|
|
6361
|
+
const [inputValue, setInputValue] = React.useState("");
|
|
6362
|
+
const prevInputValueRef = React.useRef(inputValue);
|
|
6363
|
+
const [hasEverSentMessage, setHasEverSentMessage] = React.useState(false);
|
|
6364
|
+
const [lightboxSrc, setLightboxSrc] = React.useState(null);
|
|
6365
|
+
const [lightboxAlt, setLightboxAlt] = React.useState("");
|
|
6366
|
+
const [editingMessageId, setEditingMessageId] = React.useState(null);
|
|
6367
|
+
const [isResetSessionConfirmOpen, setIsResetSessionConfirmOpen] = React.useState(false);
|
|
6368
|
+
const [analysisMode, setAnalysisMode] = React.useState("fast");
|
|
6369
|
+
const chatInputV2Ref = React.useRef(null);
|
|
6370
|
+
const messageListV2Ref = React.useRef(null);
|
|
6371
|
+
const resetToEmptyStateRef = React.useRef(false);
|
|
6372
|
+
React.useEffect(() => {
|
|
6245
6373
|
if (config.sentryDsn) {
|
|
6246
6374
|
initSentryIfNeeded(config.sentryDsn);
|
|
6247
6375
|
}
|
|
@@ -6257,7 +6385,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6257
6385
|
getSessionId,
|
|
6258
6386
|
getMessages
|
|
6259
6387
|
} = chat;
|
|
6260
|
-
|
|
6388
|
+
React.useEffect(() => {
|
|
6261
6389
|
if (resetToEmptyStateRef.current) {
|
|
6262
6390
|
if (messages.length === 0) {
|
|
6263
6391
|
setHasEverSentMessage(false);
|
|
@@ -6269,7 +6397,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6269
6397
|
setHasEverSentMessage(true);
|
|
6270
6398
|
}
|
|
6271
6399
|
}, [messages.length, hasEverSentMessage]);
|
|
6272
|
-
|
|
6400
|
+
React.useEffect(() => {
|
|
6273
6401
|
if (!editingMessageId) return;
|
|
6274
6402
|
const editingMessageStillExists = messages.some(
|
|
6275
6403
|
(message) => message.id === editingMessageId && message.role === "user"
|
|
@@ -6308,7 +6436,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6308
6436
|
}
|
|
6309
6437
|
}
|
|
6310
6438
|
);
|
|
6311
|
-
const contextValue =
|
|
6439
|
+
const contextValue = React.useMemo(
|
|
6312
6440
|
() => ({
|
|
6313
6441
|
resetSession,
|
|
6314
6442
|
clearMessages,
|
|
@@ -6335,8 +6463,8 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6335
6463
|
onAttachFileClick,
|
|
6336
6464
|
onMessageFeedback
|
|
6337
6465
|
} = callbacks;
|
|
6338
|
-
const [debugTraceExecutionId, setDebugTraceExecutionId] =
|
|
6339
|
-
const handleSubmitFeedback =
|
|
6466
|
+
const [debugTraceExecutionId, setDebugTraceExecutionId] = React.useState(null);
|
|
6467
|
+
const handleSubmitFeedback = React.useCallback(
|
|
6340
6468
|
async ({ messageId, executionId, feedback, details }) => {
|
|
6341
6469
|
if (!executionId) {
|
|
6342
6470
|
throw new Error("Cannot submit feedback before the response completes");
|
|
@@ -6367,14 +6495,14 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6367
6495
|
onMessageFeedback
|
|
6368
6496
|
]
|
|
6369
6497
|
);
|
|
6370
|
-
const onExecutionTraceClick =
|
|
6498
|
+
const onExecutionTraceClick = React.useMemo(() => {
|
|
6371
6499
|
if (!config.debug) return rawOnExecutionTraceClick;
|
|
6372
6500
|
return (data) => {
|
|
6373
6501
|
rawOnExecutionTraceClick?.(data);
|
|
6374
6502
|
if (data.executionId) setDebugTraceExecutionId(data.executionId);
|
|
6375
6503
|
};
|
|
6376
6504
|
}, [config.debug, rawOnExecutionTraceClick]);
|
|
6377
|
-
const performResetSession =
|
|
6505
|
+
const performResetSession = React.useCallback(() => {
|
|
6378
6506
|
resetToEmptyStateRef.current = true;
|
|
6379
6507
|
setEditingMessageId(null);
|
|
6380
6508
|
setIsResetSessionConfirmOpen(false);
|
|
@@ -6395,13 +6523,13 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6395
6523
|
resetSession,
|
|
6396
6524
|
stopRecording
|
|
6397
6525
|
]);
|
|
6398
|
-
const requestResetSession =
|
|
6526
|
+
const requestResetSession = React.useCallback(() => {
|
|
6399
6527
|
setIsResetSessionConfirmOpen(true);
|
|
6400
6528
|
}, []);
|
|
6401
|
-
const closeResetSessionConfirm =
|
|
6529
|
+
const closeResetSessionConfirm = React.useCallback(() => {
|
|
6402
6530
|
setIsResetSessionConfirmOpen(false);
|
|
6403
6531
|
}, []);
|
|
6404
|
-
|
|
6532
|
+
React.useImperativeHandle(ref, () => ({
|
|
6405
6533
|
resetSession: performResetSession,
|
|
6406
6534
|
clearMessages,
|
|
6407
6535
|
cancelStream,
|
|
@@ -6440,7 +6568,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6440
6568
|
slashCommands: slashCommandsConfig,
|
|
6441
6569
|
commandPermissions
|
|
6442
6570
|
} = config;
|
|
6443
|
-
const messageActions =
|
|
6571
|
+
const messageActions = React.useMemo(
|
|
6444
6572
|
() => ({
|
|
6445
6573
|
userMessageActions: {
|
|
6446
6574
|
copy: messageActionsConfig?.userMessageActions?.copy ?? true,
|
|
@@ -6456,18 +6584,18 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6456
6584
|
}),
|
|
6457
6585
|
[messageActionsConfig]
|
|
6458
6586
|
);
|
|
6459
|
-
const slashCommands =
|
|
6587
|
+
const slashCommands = React.useMemo(
|
|
6460
6588
|
() => enableSlashCommands ? filterSlashCommands(
|
|
6461
6589
|
slashCommandsConfig ?? DEFAULT_SLASH_COMMANDS,
|
|
6462
6590
|
commandPermissions
|
|
6463
6591
|
) : [],
|
|
6464
6592
|
[commandPermissions, enableSlashCommands, slashCommandsConfig]
|
|
6465
6593
|
);
|
|
6466
|
-
const isSessionParamsConfigured =
|
|
6594
|
+
const isSessionParamsConfigured = React.useMemo(() => {
|
|
6467
6595
|
if (!sessionParams) return false;
|
|
6468
6596
|
return !!(sessionParams.id?.trim() && sessionParams.name?.trim());
|
|
6469
6597
|
}, [sessionParams?.id, sessionParams?.name]);
|
|
6470
|
-
|
|
6598
|
+
React.useEffect(() => {
|
|
6471
6599
|
const wasEmpty = prevInputValueRef.current.trim() === "";
|
|
6472
6600
|
const isEmpty2 = inputValue.trim() === "";
|
|
6473
6601
|
prevInputValueRef.current = inputValue;
|
|
@@ -6534,7 +6662,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6534
6662
|
void sendMessage(text.trim(), { analysisMode: effectiveAnalysisMode });
|
|
6535
6663
|
}
|
|
6536
6664
|
};
|
|
6537
|
-
const handleVoicePress =
|
|
6665
|
+
const handleVoicePress = React.useCallback(async () => {
|
|
6538
6666
|
if (!voiceAvailable) return;
|
|
6539
6667
|
if (isRecording) {
|
|
6540
6668
|
stopRecording();
|
|
@@ -6543,7 +6671,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6543
6671
|
clearTranscript();
|
|
6544
6672
|
await startRecording();
|
|
6545
6673
|
}, [clearTranscript, isRecording, startRecording, stopRecording, voiceAvailable]);
|
|
6546
|
-
const handleEditMessageDraft =
|
|
6674
|
+
const handleEditMessageDraft = React.useCallback((messageId) => {
|
|
6547
6675
|
const targetMessage = messages.find((message) => message.id === messageId);
|
|
6548
6676
|
if (!targetMessage?.content.trim()) return;
|
|
6549
6677
|
setEditingMessageId(messageId);
|
|
@@ -6552,7 +6680,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6552
6680
|
messageListV2Ref.current?.scrollToBottom("smooth");
|
|
6553
6681
|
});
|
|
6554
6682
|
}, [messages]);
|
|
6555
|
-
const handleRetryUserMessage =
|
|
6683
|
+
const handleRetryUserMessage = React.useCallback((messageId) => {
|
|
6556
6684
|
if (isWaitingForResponse) return;
|
|
6557
6685
|
const targetMessage = messages.find(
|
|
6558
6686
|
(message) => message.id === messageId && message.role === "user"
|
|
@@ -6569,7 +6697,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6569
6697
|
});
|
|
6570
6698
|
});
|
|
6571
6699
|
}, [isWaitingForResponse, messages, sendMessage, effectiveAnalysisMode]);
|
|
6572
|
-
const handleClearEditing =
|
|
6700
|
+
const handleClearEditing = React.useCallback(() => {
|
|
6573
6701
|
setEditingMessageId(null);
|
|
6574
6702
|
}, []);
|
|
6575
6703
|
return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -6759,7 +6887,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6759
6887
|
}
|
|
6760
6888
|
) });
|
|
6761
6889
|
});
|
|
6762
|
-
var PaymanChat =
|
|
6890
|
+
var PaymanChat = React.forwardRef(
|
|
6763
6891
|
function PaymanChat2(props, ref) {
|
|
6764
6892
|
const mergedCallbacks = useSentryChatCallbacks(props.callbacks, props.config);
|
|
6765
6893
|
const chat = useChatV2(props.config, mergedCallbacks);
|