impact-chatbot 2.3.84 → 2.3.86
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.cjs.js +79 -16
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +80 -17
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -675,8 +675,11 @@ const handleMessageLike = async (question, liked, setLoadingState, displaySnackM
|
|
|
675
675
|
try {
|
|
676
676
|
let request;
|
|
677
677
|
if (currentMode === "agent") {
|
|
678
|
+
// Use the session stored on this specific message. The live sessionId is
|
|
679
|
+
// reset once a flow completes / awaits follow-up, so relying on it would
|
|
680
|
+
// send an empty session_id or the session of a newer chat.
|
|
678
681
|
const agentPayload = {
|
|
679
|
-
session_id: sessionId,
|
|
682
|
+
session_id: activeMessage?.chatSessionId || activeMessage?.sessionId || sessionId,
|
|
680
683
|
liked,
|
|
681
684
|
};
|
|
682
685
|
request = await likeDislikeCommentForAgent(agentPayload, baseUrl);
|
|
@@ -1439,31 +1442,50 @@ const ThinkinHeaderInfo = (props) => {
|
|
|
1439
1442
|
});
|
|
1440
1443
|
const { streamStartTime, isStreamCompleted, finalElapsedSeconds, thinkingHeaderMessage } = thinkingContext;
|
|
1441
1444
|
const [elapsed, setElapsed] = React.useState(0);
|
|
1445
|
+
const [frozenText, setFrozenText] = React.useState(null);
|
|
1442
1446
|
const intervalRef = React.useRef(null);
|
|
1443
1447
|
// Once this instance sees "completed", freeze it permanently so a future
|
|
1444
1448
|
// chat's streamStartTime doesn't cause it to start ticking again.
|
|
1445
1449
|
const frozenRef = React.useRef(false);
|
|
1446
1450
|
const frozenTextRef = React.useRef(null);
|
|
1447
|
-
|
|
1451
|
+
// The streamStartTime this instance latched onto. Used to detect when a
|
|
1452
|
+
// different stream has taken over (e.g. the user asked a new question while
|
|
1453
|
+
// this message's step form was still waiting for input).
|
|
1454
|
+
const ownStartTimeRef = React.useRef(null);
|
|
1455
|
+
/**
|
|
1456
|
+
* Freezes this instance permanently on a final label and elapsed value.
|
|
1457
|
+
*/
|
|
1458
|
+
const freeze = (text, seconds) => {
|
|
1459
|
+
frozenRef.current = true;
|
|
1460
|
+
frozenTextRef.current = text;
|
|
1461
|
+
setFrozenText(text);
|
|
1462
|
+
setElapsed(seconds);
|
|
1463
|
+
};
|
|
1448
1464
|
React.useEffect(() => {
|
|
1449
1465
|
// If already frozen (stream completed), NEVER unfreeze.
|
|
1450
1466
|
// This prevents a new chat's streamStartTime from restarting this timer.
|
|
1451
1467
|
if (frozenRef.current)
|
|
1452
1468
|
return;
|
|
1453
|
-
//
|
|
1454
|
-
if (
|
|
1455
|
-
|
|
1469
|
+
// Adopt the first non-null streamStartTime we see as this instance's own
|
|
1470
|
+
if (ownStartTimeRef.current === null && streamStartTime) {
|
|
1471
|
+
ownStartTimeRef.current = streamStartTime;
|
|
1456
1472
|
}
|
|
1473
|
+
const ownStartTime = ownStartTimeRef.current;
|
|
1457
1474
|
// Clear any existing interval
|
|
1458
1475
|
if (intervalRef.current) {
|
|
1459
1476
|
clearInterval(intervalRef.current);
|
|
1460
1477
|
intervalRef.current = null;
|
|
1461
1478
|
}
|
|
1462
1479
|
if (isStreamCompleted && typeof finalElapsedSeconds === 'number') {
|
|
1463
|
-
// Freeze this instance
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1480
|
+
// Freeze this instance - it will never tick again
|
|
1481
|
+
freeze(`Completed in ${formatElapsedTime(finalElapsedSeconds)}`, finalElapsedSeconds);
|
|
1482
|
+
}
|
|
1483
|
+
else if (ownStartTime !== null && streamStartTime !== ownStartTime) {
|
|
1484
|
+
// A different stream has started (new question) while this one never
|
|
1485
|
+
// completed - typically an abandoned step form. Freeze on this
|
|
1486
|
+
// instance's OWN elapsed time instead of following the new stream.
|
|
1487
|
+
const ownElapsed = Math.floor((Date.now() - ownStartTime) / 1000);
|
|
1488
|
+
freeze(`Completed in ${formatElapsedTime(ownElapsed)}`, ownElapsed);
|
|
1467
1489
|
}
|
|
1468
1490
|
else if (streamStartTime && !isStreamCompleted) {
|
|
1469
1491
|
// Live timer — update every second
|
|
@@ -1484,8 +1506,8 @@ const ThinkinHeaderInfo = (props) => {
|
|
|
1484
1506
|
}, [streamStartTime, isStreamCompleted, finalElapsedSeconds]);
|
|
1485
1507
|
// Determine display text
|
|
1486
1508
|
let displayText = thinkingHeaderMessage || '';
|
|
1487
|
-
if (frozenRef.current && frozenTextRef.current) {
|
|
1488
|
-
displayText = frozenTextRef.current;
|
|
1509
|
+
if (frozenText || (frozenRef.current && frozenTextRef.current)) {
|
|
1510
|
+
displayText = frozenText || frozenTextRef.current;
|
|
1489
1511
|
}
|
|
1490
1512
|
else if (streamStartTime && !isStreamCompleted) {
|
|
1491
1513
|
displayText = `Working for ${formatElapsedTime(elapsed)}`;
|
|
@@ -2479,6 +2501,20 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2479
2501
|
}
|
|
2480
2502
|
if (data.flow_type === "agent" && data.actionType === "direct") {
|
|
2481
2503
|
data.baseUrl = baseUrl;
|
|
2504
|
+
// Reset the timer before the request goes out (same as index.jsx
|
|
2505
|
+
// handleSendMessage). Without this the new ThinkinHeaderInfo mounts while
|
|
2506
|
+
// the previous response's "completed" state is still in Redux and freezes
|
|
2507
|
+
// itself on that stale elapsed time.
|
|
2508
|
+
// streamStartTime stays null here: processStream sets it, so a question
|
|
2509
|
+
// has exactly one start time (two would make the new header look like a
|
|
2510
|
+
// superseded one and freeze it at 0m:00s).
|
|
2511
|
+
dispatch(smartBotActions.setThinkingContext({
|
|
2512
|
+
thinkingContent: "",
|
|
2513
|
+
thinkingHeaderMessage: "Working for 0m:00s",
|
|
2514
|
+
streamStartTime: null,
|
|
2515
|
+
isStreamCompleted: false,
|
|
2516
|
+
finalElapsedSeconds: null,
|
|
2517
|
+
}));
|
|
2482
2518
|
prepareDataAndSendToAgent(data, false, {
|
|
2483
2519
|
chatbotContext: chatbotContext,
|
|
2484
2520
|
setChatbotContext: smartBotActions.setChatbotContext,
|
|
@@ -5337,6 +5373,13 @@ const sseevent = (message, messageToStoreRef) => {
|
|
|
5337
5373
|
? parsedData.chat_id
|
|
5338
5374
|
: "";
|
|
5339
5375
|
messageToStoreRef.current.sessionId = parsedData?.session_id;
|
|
5376
|
+
// Sticky copy of the session id this message belongs to. sessionId gets
|
|
5377
|
+
// cleared on completed/follow-up so the next user message starts a fresh
|
|
5378
|
+
// session, but message level actions (like/dislike) still need to refer
|
|
5379
|
+
// to the session that actually produced this response.
|
|
5380
|
+
if (parsedData?.session_id) {
|
|
5381
|
+
messageToStoreRef.current.chatSessionId = parsedData.session_id;
|
|
5382
|
+
}
|
|
5340
5383
|
}
|
|
5341
5384
|
if (messageToStoreRef.current.currentMode === "navigation" &&
|
|
5342
5385
|
parsedData?.session_id) {
|
|
@@ -8685,7 +8728,7 @@ const StreamedContent = ({ botData, botProps }) => {
|
|
|
8685
8728
|
const retryTimerRef = React.useRef(null); // Interval ref for countdown
|
|
8686
8729
|
const retryCountdownRef = React.useRef(0); // Non-state countdown for interval callback
|
|
8687
8730
|
const thinkingContentRef = React.useRef("");
|
|
8688
|
-
reactRedux.useSelector((state) => {
|
|
8731
|
+
const thinkingContext = reactRedux.useSelector((state) => {
|
|
8689
8732
|
return state.smartBotReducer.thinkingContext;
|
|
8690
8733
|
});
|
|
8691
8734
|
const stepRef = React.useRef(_isAbortedRemount
|
|
@@ -8708,7 +8751,10 @@ const StreamedContent = ({ botData, botProps }) => {
|
|
|
8708
8751
|
const thinkingStartTimeRef = React.useRef(null);
|
|
8709
8752
|
const thinkingTimeFinalRef = React.useRef(0);
|
|
8710
8753
|
const thinkingHeaderMessageRef = React.useRef("Working for 0m:00s");
|
|
8711
|
-
|
|
8754
|
+
// Inherit the in-flight start time so a remount (e.g. tab switch, where
|
|
8755
|
+
// processStream is not re-run) keeps the original one instead of resetting.
|
|
8756
|
+
// Null for a fresh question - processStream sets it.
|
|
8757
|
+
const streamStartTimeRef = React.useRef(thinkingContext?.isStreamCompleted ? null : thinkingContext?.streamStartTime || null);
|
|
8712
8758
|
const thinkingDoneRef = React.useRef(false);
|
|
8713
8759
|
const thinkingStartedRef = React.useRef(false);
|
|
8714
8760
|
const setThinkingContentRef = React.useRef(setThinkingContent); // Store current setThinkingContent function
|
|
@@ -9683,7 +9729,12 @@ const StreamedContent = ({ botData, botProps }) => {
|
|
|
9683
9729
|
},
|
|
9684
9730
|
};
|
|
9685
9731
|
const hasStepFormWidgets = !isEmpty(stepFormDataMapRef.current);
|
|
9686
|
-
|
|
9732
|
+
// response.session_id is intentionally blank once the flow completes, so
|
|
9733
|
+
// keep the retained session separately and stamp it on the stored message.
|
|
9734
|
+
const messageChatSessionId = messageToStoreRef.current.chatSessionId ||
|
|
9735
|
+
messageToStoreRef.current.sessionId ||
|
|
9736
|
+
"";
|
|
9737
|
+
Promise.resolve(processResponse(response, botData.inputBody, currentMode, botData.utilityObject.customChatConfig, {
|
|
9687
9738
|
newChatData: chatDataInfoRef,
|
|
9688
9739
|
isTabEnabled: true,
|
|
9689
9740
|
steps: stepRef.current.map(s => ({ ...s })),
|
|
@@ -9691,7 +9742,15 @@ const StreamedContent = ({ botData, botProps }) => {
|
|
|
9691
9742
|
questions: [...questionsRef.current],
|
|
9692
9743
|
questionsStepsMap: { ...questionsStepsMapRef.current },
|
|
9693
9744
|
stepFormDataMap: { ...stepFormDataMapRef.current },
|
|
9694
|
-
}, activeConversationId)
|
|
9745
|
+
}, activeConversationId)).then(() => {
|
|
9746
|
+
if (!messageChatSessionId)
|
|
9747
|
+
return;
|
|
9748
|
+
const storedMessages = chatDataInfoRef.current?.[currentMode]?.conversations?.[activeConversationId]?.messages;
|
|
9749
|
+
if (storedMessages?.length) {
|
|
9750
|
+
storedMessages[storedMessages.length - 1].chatSessionId =
|
|
9751
|
+
messageChatSessionId;
|
|
9752
|
+
}
|
|
9753
|
+
});
|
|
9695
9754
|
// [
|
|
9696
9755
|
// {
|
|
9697
9756
|
// header: "Finding relevant information",
|
|
@@ -15855,10 +15914,14 @@ const SmartBot = (props) => {
|
|
|
15855
15914
|
answerMode: answerMode,
|
|
15856
15915
|
};
|
|
15857
15916
|
// if(!isEmpty(userInput)) {
|
|
15917
|
+
// Clear the previous response's completed state so the incoming
|
|
15918
|
+
// ThinkinHeaderInfo doesn't freeze on it. streamStartTime stays null
|
|
15919
|
+
// here: processStream sets it, so a question has exactly one start
|
|
15920
|
+
// time (two would make the new header look like a superseded one).
|
|
15858
15921
|
dispatch(smartBotActions.setThinkingContext({
|
|
15859
15922
|
thinkingContent: "",
|
|
15860
15923
|
thinkingHeaderMessage: "Working for 0m:00s",
|
|
15861
|
-
streamStartTime:
|
|
15924
|
+
streamStartTime: null,
|
|
15862
15925
|
isStreamCompleted: false,
|
|
15863
15926
|
finalElapsedSeconds: null,
|
|
15864
15927
|
}));
|