impact-chatbot 2.3.64 → 2.3.66
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 +204 -30
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +204 -30
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -315,7 +315,7 @@ const useBotConfiguration = (setRefreshLoader, setEnableRefreshAction, dispatch)
|
|
|
315
315
|
*/
|
|
316
316
|
const parseResponse = (data, type, agentId = "", currentMode = "", disableTimeAndName = false, sessionId = "", utilityData = {}, inputBody = null, utilityObject = {}) => {
|
|
317
317
|
const timeString = disableTimeAndName ? "" : moment().format("DD-MM-YYYY HH:mm:ss");
|
|
318
|
-
const userName = disableTimeAndName ? "" : "
|
|
318
|
+
const userName = disableTimeAndName ? "" : "Iris";
|
|
319
319
|
switch (type || data?.type) {
|
|
320
320
|
case "text":
|
|
321
321
|
return {
|
|
@@ -1392,7 +1392,7 @@ const useAgentFlow = (dateFormat, chatDataRef, currentMode, setShowChatPlacehold
|
|
|
1392
1392
|
hasDirectActionType: false,
|
|
1393
1393
|
};
|
|
1394
1394
|
const loaderData = {
|
|
1395
|
-
userName: "
|
|
1395
|
+
userName: "Iris",
|
|
1396
1396
|
timeStamp: currentTimeString,
|
|
1397
1397
|
userType: "loader",
|
|
1398
1398
|
};
|
|
@@ -1958,7 +1958,7 @@ const useAgentFlow = (dateFormat, chatDataRef, currentMode, setShowChatPlacehold
|
|
|
1958
1958
|
const failResponseText = {
|
|
1959
1959
|
timeStamp: getCurrentDateTimeString(),
|
|
1960
1960
|
userType: "bot",
|
|
1961
|
-
userName: "
|
|
1961
|
+
userName: "Iris",
|
|
1962
1962
|
bodyText: error?.response?.data?.data?.error?.response
|
|
1963
1963
|
? error?.response?.data?.data?.error?.response
|
|
1964
1964
|
: "Sorry, chatbot is not available now",
|
|
@@ -2202,7 +2202,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2202
2202
|
return {
|
|
2203
2203
|
timeStamp: timeString,
|
|
2204
2204
|
userType: "bot",
|
|
2205
|
-
userName: "
|
|
2205
|
+
userName: "Iris",
|
|
2206
2206
|
headerTitle: headerTitle,
|
|
2207
2207
|
bodyType: "chips",
|
|
2208
2208
|
bodyText: screens.map((screen) => ({
|
|
@@ -2256,7 +2256,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2256
2256
|
flow_type: flowType,
|
|
2257
2257
|
};
|
|
2258
2258
|
const loaderData = {
|
|
2259
|
-
userName: "
|
|
2259
|
+
userName: "Iris",
|
|
2260
2260
|
timeStamp: currentTimeString,
|
|
2261
2261
|
userType: "loader",
|
|
2262
2262
|
};
|
|
@@ -2290,7 +2290,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2290
2290
|
const failResponseText = {
|
|
2291
2291
|
timeStamp: getCurrentDateTimeString(),
|
|
2292
2292
|
userType: "bot",
|
|
2293
|
-
userName: "
|
|
2293
|
+
userName: "Iris",
|
|
2294
2294
|
bodyText: options.data.data.message,
|
|
2295
2295
|
enableLikes: false,
|
|
2296
2296
|
headerTitle: "",
|
|
@@ -2309,7 +2309,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2309
2309
|
const failResponseText = {
|
|
2310
2310
|
timeStamp: getCurrentDateTimeString(),
|
|
2311
2311
|
userType: "bot",
|
|
2312
|
-
userName: "
|
|
2312
|
+
userName: "Iris",
|
|
2313
2313
|
bodyText: "Failed to fetch user screens. Please try again later.",
|
|
2314
2314
|
headerTitle: "",
|
|
2315
2315
|
enableLikes: false,
|
|
@@ -2381,7 +2381,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2381
2381
|
hasDirectActionType: fetchQuestions,
|
|
2382
2382
|
};
|
|
2383
2383
|
const loaderData = {
|
|
2384
|
-
userName: "
|
|
2384
|
+
userName: "Iris",
|
|
2385
2385
|
timeStamp: currentTimeString,
|
|
2386
2386
|
userType: "loader",
|
|
2387
2387
|
};
|
|
@@ -2501,7 +2501,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2501
2501
|
const failResponseText = {
|
|
2502
2502
|
timeStamp: getCurrentDateTimeString(),
|
|
2503
2503
|
userType: "bot",
|
|
2504
|
-
userName: "
|
|
2504
|
+
userName: "Iris",
|
|
2505
2505
|
bodyText: error?.response?.data?.data?.error?.response
|
|
2506
2506
|
? error?.response?.data?.data?.error?.response
|
|
2507
2507
|
: "Sorry, chatbot is not available now",
|
|
@@ -2712,10 +2712,10 @@ const useChatSession = (chatDataRef, setFlowType, setScreenName, setUserInput, s
|
|
|
2712
2712
|
{
|
|
2713
2713
|
timeStamp: getCurrentDateTimeString(),
|
|
2714
2714
|
userType: "bot",
|
|
2715
|
-
userName: "
|
|
2715
|
+
userName: "Iris",
|
|
2716
2716
|
headerTitle: `Hi ${getUserName()}!`,
|
|
2717
2717
|
bodyType: "text",
|
|
2718
|
-
bodyText: `I am
|
|
2718
|
+
bodyText: `I am Iris, your virtual assistant. I am here to help you on anything you are looking for in IA Smart Platform`,
|
|
2719
2719
|
},
|
|
2720
2720
|
];
|
|
2721
2721
|
// chatDataRef.current[currentMode].conversations[
|
|
@@ -4881,7 +4881,7 @@ const ChatPlaceholder = (props) => {
|
|
|
4881
4881
|
agentId: card.agentId || card.id
|
|
4882
4882
|
}));
|
|
4883
4883
|
const dataToMap = legacyAgentScreen || displayQuestions ? transformedCardList : rectangleData;
|
|
4884
|
-
return (jsxs("div", { className: classes.placeholderContainer, children: [jsx("div", { className: classes.centerIconContainer, children: jsx(SvgCenter3D, { className: classes.centerIcon }) }), jsxs("div", { className: classes.headingContainer, children: [jsx(Typography, { variant: "h1", className: classes.heading, children: "
|
|
4884
|
+
return (jsxs("div", { className: classes.placeholderContainer, children: [jsx("div", { className: classes.centerIconContainer, children: jsx(SvgCenter3D, { className: classes.centerIcon }) }), jsxs("div", { className: classes.headingContainer, children: [jsx(Typography, { variant: "h1", className: classes.heading, children: "Iris's Capabilities" }), jsx("span", { className: classes.alphaTag, children: "Beta" })] }), jsx(Typography, { variant: "body1", className: classes.headingHelperText, children: "Discover potential issues & opportunities Iris can help you with!" }), jsx("div", { className: classes.rectanglesContainer, children: dataToMap.map((item, index) => (jsx(Rectangle, { type: item.type, icon: item.icon, title: item.title, description: item.description, onClick: () => handleRectangleClick(item?.agentId, item?.title), hoverable: legacyAgentScreen || displayQuestions }, index))) })] }));
|
|
4885
4885
|
};
|
|
4886
4886
|
|
|
4887
4887
|
const dateFormat = "DD-MM-YYYY HH:mm:ss";
|
|
@@ -7127,15 +7127,43 @@ const StepFormContent = ({ formData, messageIndex = 0, isFormDisabled = false, s
|
|
|
7127
7127
|
const chatbotFilterOptions = useSelector((state) => state.smartBotReducer.chatbotFilterOptions);
|
|
7128
7128
|
const dimensionHierarchies = useSelector((state) => state.userRoleManagementService?.dimensionHierarchies);
|
|
7129
7129
|
const [isFormSubmitted, setIsFormSubmitted] = useState(false);
|
|
7130
|
+
const [isTimedOut, setIsTimedOut] = useState(false);
|
|
7131
|
+
const timeoutRef = useRef(null);
|
|
7132
|
+
// 30-minute inactivity timeout: disable form and switch to agent_response tab
|
|
7133
|
+
const FORM_TIMEOUT_MS = 30 * 60 * 1000;
|
|
7134
|
+
useEffect(() => {
|
|
7135
|
+
if (isFormDisabled || isFormSubmitted || isTimedOut)
|
|
7136
|
+
return;
|
|
7137
|
+
const startTime = Date.now();
|
|
7138
|
+
timeoutRef.current = setTimeout(() => {
|
|
7139
|
+
setIsTimedOut(true);
|
|
7140
|
+
const elapsedSeconds = Math.floor((Date.now() - startTime) / 1000);
|
|
7141
|
+
window.dispatchEvent(new CustomEvent("stepFormTimeout", { detail: { elapsedSeconds } }));
|
|
7142
|
+
}, FORM_TIMEOUT_MS);
|
|
7143
|
+
return () => {
|
|
7144
|
+
if (timeoutRef.current) {
|
|
7145
|
+
clearTimeout(timeoutRef.current);
|
|
7146
|
+
timeoutRef.current = null;
|
|
7147
|
+
}
|
|
7148
|
+
};
|
|
7149
|
+
}, [isFormDisabled, isFormSubmitted, isTimedOut]);
|
|
7150
|
+
// Clear timeout when form is submitted
|
|
7151
|
+
useEffect(() => {
|
|
7152
|
+
if (isFormSubmitted && timeoutRef.current) {
|
|
7153
|
+
clearTimeout(timeoutRef.current);
|
|
7154
|
+
timeoutRef.current = null;
|
|
7155
|
+
}
|
|
7156
|
+
}, [isFormSubmitted]);
|
|
7130
7157
|
useEffect(() => {
|
|
7131
7158
|
if (stepFormStreamData?.status === "streaming_start") {
|
|
7132
7159
|
setIsFormSubmitted(true);
|
|
7133
7160
|
}
|
|
7134
7161
|
}, [stepFormStreamData]);
|
|
7135
|
-
// Reset isFormSubmitted when parent signals the form should be enabled (new step_form from restream)
|
|
7162
|
+
// Reset isFormSubmitted and isTimedOut when parent signals the form should be enabled (new step_form from restream)
|
|
7136
7163
|
useEffect(() => {
|
|
7137
7164
|
if (!isFormDisabled) {
|
|
7138
7165
|
setIsFormSubmitted(false);
|
|
7166
|
+
setIsTimedOut(false);
|
|
7139
7167
|
}
|
|
7140
7168
|
}, [isFormDisabled]);
|
|
7141
7169
|
const [isFilterSetOpen, setIsFilterSetOpen] = useState(false);
|
|
@@ -7206,8 +7234,8 @@ const StepFormContent = ({ formData, messageIndex = 0, isFormDisabled = false, s
|
|
|
7206
7234
|
return val && (Array.isArray(val) ? val.length > 0 : !!val);
|
|
7207
7235
|
});
|
|
7208
7236
|
}, [persistedFormValues, messageIndex]);
|
|
7209
|
-
const formFieldsDisabled = isFormDisabled || isFilterSelected || isFormSubmitted;
|
|
7210
|
-
const savedFilterDisabled = isFormDisabled || isFormFieldUsed || isFormSubmitted;
|
|
7237
|
+
const formFieldsDisabled = isFormDisabled || isFilterSelected || isFormSubmitted || isTimedOut;
|
|
7238
|
+
const savedFilterDisabled = isFormDisabled || isFormFieldUsed || isFormSubmitted || isTimedOut;
|
|
7211
7239
|
const requiredFieldsFilled = useMemo(() => {
|
|
7212
7240
|
if (!formData || !Array.isArray(formData))
|
|
7213
7241
|
return false;
|
|
@@ -7795,7 +7823,40 @@ const AgentResponse$1 = (props) => {
|
|
|
7795
7823
|
|
|
7796
7824
|
const StepsResponseTab = (props) => {
|
|
7797
7825
|
const { steps, setSteps, stepsDone, setStepsDone, finalStepDone, setFinalStepDone, content, isStreaming, stepChange, currentMode, questions, questionsStepsMap, stepFormDataMap, isFormDisabled, streamingWidgetData, isRetrying, } = props;
|
|
7826
|
+
const dispatch = useDispatch();
|
|
7827
|
+
const thinkingContext = useSelector((state) => state.smartBotReducer.thinkingContext);
|
|
7828
|
+
const streamStartTimeRef = useRef(thinkingContext?.streamStartTime);
|
|
7829
|
+
// Keep streamStartTime ref in sync with Redux for use in event handler closures
|
|
7830
|
+
useEffect(() => {
|
|
7831
|
+
streamStartTimeRef.current = thinkingContext?.streamStartTime;
|
|
7832
|
+
}, [thinkingContext?.streamStartTime]);
|
|
7798
7833
|
const [tabValue, setTabValue] = useState("steps");
|
|
7834
|
+
const [timeoutMessage, setTimeoutMessage] = useState("");
|
|
7835
|
+
// Switch to agent_response tab on form inactivity timeout (30 min)
|
|
7836
|
+
useEffect(() => {
|
|
7837
|
+
const handleStepFormTimeout = () => {
|
|
7838
|
+
setTimeoutMessage("This session timed out due to inactivity. Please start a new message to continue.");
|
|
7839
|
+
setTabValue("agent_response");
|
|
7840
|
+
dispatch(setMinimizedStreamData(null));
|
|
7841
|
+
const elapsed = streamStartTimeRef.current
|
|
7842
|
+
? Math.floor((Date.now() - streamStartTimeRef.current) / 1000)
|
|
7843
|
+
: null;
|
|
7844
|
+
const mins = elapsed != null ? Math.floor(elapsed / 60) : 0;
|
|
7845
|
+
const secs = elapsed != null ? elapsed % 60 : 0;
|
|
7846
|
+
const timedOutLabel = `Worked for ${mins}m:${String(secs).padStart(2, '0')}s`;
|
|
7847
|
+
dispatch(setThinkingContext({
|
|
7848
|
+
streamStartTime: null,
|
|
7849
|
+
isStreamCompleted: true,
|
|
7850
|
+
finalElapsedSeconds: elapsed,
|
|
7851
|
+
thinkingHeaderMessage: timedOutLabel,
|
|
7852
|
+
thinkingContent: "",
|
|
7853
|
+
}));
|
|
7854
|
+
};
|
|
7855
|
+
window.addEventListener("stepFormTimeout", handleStepFormTimeout);
|
|
7856
|
+
return () => {
|
|
7857
|
+
window.removeEventListener("stepFormTimeout", handleStepFormTimeout);
|
|
7858
|
+
};
|
|
7859
|
+
}, []);
|
|
7799
7860
|
// When retry countdown starts, switch to agent_response to show it.
|
|
7800
7861
|
// When retry actually fires (isRetrying goes false + isStreaming goes true), switch back to steps.
|
|
7801
7862
|
useEffect(() => {
|
|
@@ -7824,7 +7885,7 @@ const StepsResponseTab = (props) => {
|
|
|
7824
7885
|
},
|
|
7825
7886
|
], tabPanels: [
|
|
7826
7887
|
jsx(Steps$1, { steps: steps, setSteps: setSteps, done: stepsDone, setDone: setStepsDone, setTabValue: setTabValue, finalStepDone: finalStepDone, setFinalStepDone: setFinalStepDone, stepChange: stepChange, currentMode: currentMode, questions: questions, questionsStepsMap: questionsStepsMap, stepFormDataMap: stepFormDataMap, isFormDisabled: isFormDisabled }),
|
|
7827
|
-
jsx(AgentResponse$1, { content: content, isStreaming: isStreaming, streamingWidgetData: streamingWidgetData }),
|
|
7888
|
+
jsxs(Fragment, { children: [jsx(AgentResponse$1, { content: content, isStreaming: isStreaming, streamingWidgetData: streamingWidgetData }), timeoutMessage && (jsx("div", { style: { marginTop: "8px", padding: "0 8px" }, children: jsx(TextRenderer, { text: timeoutMessage, thinking: "" }) }))] }),
|
|
7828
7889
|
], value: tabValue }) }));
|
|
7829
7890
|
};
|
|
7830
7891
|
|
|
@@ -8652,6 +8713,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
8652
8713
|
// Check if this is a user-initiated abort (should not trigger retry)
|
|
8653
8714
|
const isUserAbort = event.reason === "Network request aborted";
|
|
8654
8715
|
event.statusCode === 503;
|
|
8716
|
+
const isAgentUnavailable = event.statusCode === 502 || event.statusCode === 404;
|
|
8655
8717
|
if (isThinking) {
|
|
8656
8718
|
setIsThinking(false);
|
|
8657
8719
|
const endTime = Date.now();
|
|
@@ -8662,8 +8724,50 @@ const StreamedContent = ({ botData }) => {
|
|
|
8662
8724
|
thinkingStartTimeRef.current = finalThinkingTime;
|
|
8663
8725
|
messageToStoreRef.current.chatData.thinkingResponse.thinkingTime = finalThinkingTime;
|
|
8664
8726
|
}
|
|
8727
|
+
// Agent unavailable (502/404) — show specific message, no retry
|
|
8728
|
+
if (isAgentUnavailable) {
|
|
8729
|
+
setWasStreamingAborted(true);
|
|
8730
|
+
wasStreamingAbortedRef.current = true;
|
|
8731
|
+
const currentSteps = stepRef.current;
|
|
8732
|
+
if (currentSteps.length > 0) {
|
|
8733
|
+
const lastStep = currentSteps[currentSteps.length - 1];
|
|
8734
|
+
if (lastStep.step_status === "not-completed") {
|
|
8735
|
+
lastStep.step_status = "completed";
|
|
8736
|
+
}
|
|
8737
|
+
stepRef.current = [...currentSteps];
|
|
8738
|
+
setSteps([...currentSteps]);
|
|
8739
|
+
}
|
|
8740
|
+
const agentUnavailableMessage = "Agent isn't available right now. Please contact your administrator or try again later.";
|
|
8741
|
+
const hasExistingWidgetsOnUnavail = messageToStoreRef.current.appendedData &&
|
|
8742
|
+
(isArray(messageToStoreRef.current.appendedData)
|
|
8743
|
+
? messageToStoreRef.current.appendedData.length > 0
|
|
8744
|
+
: Object.keys(messageToStoreRef.current.appendedData).length > 0);
|
|
8745
|
+
if (hasExistingWidgetsOnUnavail) {
|
|
8746
|
+
const errorWidget = { type: "text", response: agentUnavailableMessage };
|
|
8747
|
+
if (isArray(messageToStoreRef.current.appendedData)) {
|
|
8748
|
+
messageToStoreRef.current.appendedData.push(errorWidget);
|
|
8749
|
+
}
|
|
8750
|
+
else {
|
|
8751
|
+
messageToStoreRef.current.appendedData = [messageToStoreRef.current.appendedData, errorWidget];
|
|
8752
|
+
}
|
|
8753
|
+
}
|
|
8754
|
+
else {
|
|
8755
|
+
messageToStoreRef.current.chatData.response = agentUnavailableMessage;
|
|
8756
|
+
}
|
|
8757
|
+
setContent(agentUnavailableMessage);
|
|
8758
|
+
dispatch(setMinimizedStreamData({
|
|
8759
|
+
isStreaming: false,
|
|
8760
|
+
stepHeader: questionsRef.current[questionsRef.current.length - 1] || "Agent unavailable",
|
|
8761
|
+
stepSubHeader: "Connection closed",
|
|
8762
|
+
stepStatus: "completed",
|
|
8763
|
+
streamStartTime: streamStartTimeRef.current,
|
|
8764
|
+
actionCount: questionsRef.current.length || 1,
|
|
8765
|
+
}));
|
|
8766
|
+
setStepsDone(true);
|
|
8767
|
+
setIsStreamingDone(true);
|
|
8768
|
+
}
|
|
8665
8769
|
// Check if we can auto-retry (abrupt close or 503, but not user abort)
|
|
8666
|
-
if (!isUserAbort && retryCountRef.current < MAX_RETRY_COUNT) {
|
|
8770
|
+
else if (!isUserAbort && retryCountRef.current < MAX_RETRY_COUNT) {
|
|
8667
8771
|
// Still have retries left — start countdown instead of showing final error
|
|
8668
8772
|
setStepsDone(true); // Switch to agent_response tab to show countdown
|
|
8669
8773
|
const retryMessage = "The service is temporarily unavailable because of an unusual load. Please wait a moment and try again.";
|
|
@@ -8683,8 +8787,26 @@ const StreamedContent = ({ botData }) => {
|
|
|
8683
8787
|
stepRef.current = [...currentSteps];
|
|
8684
8788
|
setSteps([...currentSteps]);
|
|
8685
8789
|
}
|
|
8686
|
-
|
|
8687
|
-
|
|
8790
|
+
// Append the error message at the bottom of any existing content.
|
|
8791
|
+
// If widgets already exist in appendedData, append as the last widget
|
|
8792
|
+
// so it renders AFTER the already-received content (not at the top).
|
|
8793
|
+
const finalMessage = "The service is temporarily unavailable because of an unusual load. Please wait a moment and try again.";
|
|
8794
|
+
const hasExistingWidgetsOnErr = messageToStoreRef.current.appendedData &&
|
|
8795
|
+
(isArray(messageToStoreRef.current.appendedData)
|
|
8796
|
+
? messageToStoreRef.current.appendedData.length > 0
|
|
8797
|
+
: Object.keys(messageToStoreRef.current.appendedData).length > 0);
|
|
8798
|
+
if (hasExistingWidgetsOnErr) {
|
|
8799
|
+
const errorWidget = { type: "text", response: finalMessage };
|
|
8800
|
+
if (isArray(messageToStoreRef.current.appendedData)) {
|
|
8801
|
+
messageToStoreRef.current.appendedData.push(errorWidget);
|
|
8802
|
+
}
|
|
8803
|
+
else {
|
|
8804
|
+
messageToStoreRef.current.appendedData = [messageToStoreRef.current.appendedData, errorWidget];
|
|
8805
|
+
}
|
|
8806
|
+
}
|
|
8807
|
+
else {
|
|
8808
|
+
messageToStoreRef.current.chatData.response = finalMessage;
|
|
8809
|
+
}
|
|
8688
8810
|
setContent(finalMessage);
|
|
8689
8811
|
dispatch(setMinimizedStreamData({
|
|
8690
8812
|
isStreaming: false,
|
|
@@ -8726,9 +8848,10 @@ const StreamedContent = ({ botData }) => {
|
|
|
8726
8848
|
startRetryCountdown();
|
|
8727
8849
|
}
|
|
8728
8850
|
else {
|
|
8729
|
-
// Retries exhausted — show final
|
|
8851
|
+
// Retries exhausted — show final message
|
|
8730
8852
|
setWasStreamingAborted(true);
|
|
8731
8853
|
wasStreamingAbortedRef.current = true;
|
|
8854
|
+
// Mark the last in-progress step as completed
|
|
8732
8855
|
const currentSteps = stepRef.current;
|
|
8733
8856
|
if (currentSteps.length > 0) {
|
|
8734
8857
|
const lastStep = currentSteps[currentSteps.length - 1];
|
|
@@ -8738,8 +8861,26 @@ const StreamedContent = ({ botData }) => {
|
|
|
8738
8861
|
stepRef.current = [...currentSteps];
|
|
8739
8862
|
setSteps([...currentSteps]);
|
|
8740
8863
|
}
|
|
8741
|
-
|
|
8742
|
-
|
|
8864
|
+
// Append the error message at the bottom of any existing content.
|
|
8865
|
+
// If widgets already exist in appendedData, append as the last widget
|
|
8866
|
+
// so it renders AFTER the already-received content (not at the top).
|
|
8867
|
+
const finalMessage = "The service is temporarily unavailable because of an unusual load. Please wait a moment and try again.";
|
|
8868
|
+
const hasExistingWidgets = messageToStoreRef.current.appendedData &&
|
|
8869
|
+
(isArray(messageToStoreRef.current.appendedData)
|
|
8870
|
+
? messageToStoreRef.current.appendedData.length > 0
|
|
8871
|
+
: Object.keys(messageToStoreRef.current.appendedData).length > 0);
|
|
8872
|
+
if (hasExistingWidgets) {
|
|
8873
|
+
const errorWidget = { type: "text", response: finalMessage };
|
|
8874
|
+
if (isArray(messageToStoreRef.current.appendedData)) {
|
|
8875
|
+
messageToStoreRef.current.appendedData.push(errorWidget);
|
|
8876
|
+
}
|
|
8877
|
+
else {
|
|
8878
|
+
messageToStoreRef.current.appendedData = [messageToStoreRef.current.appendedData, errorWidget];
|
|
8879
|
+
}
|
|
8880
|
+
}
|
|
8881
|
+
else {
|
|
8882
|
+
messageToStoreRef.current.chatData.response = finalMessage;
|
|
8883
|
+
}
|
|
8743
8884
|
setContent(finalMessage);
|
|
8744
8885
|
dispatch(setMinimizedStreamData({
|
|
8745
8886
|
isStreaming: false,
|
|
@@ -8944,19 +9085,19 @@ const StreamedContent = ({ botData }) => {
|
|
|
8944
9085
|
// [
|
|
8945
9086
|
// {
|
|
8946
9087
|
// header: "Finding relevant information",
|
|
8947
|
-
// sub_header: "
|
|
9088
|
+
// sub_header: "Iris is working to identify relevant information to user answer user query",
|
|
8948
9089
|
// step_status: "not-completed",
|
|
8949
9090
|
// },
|
|
8950
9091
|
// ];
|
|
8951
9092
|
// [
|
|
8952
9093
|
// {
|
|
8953
9094
|
// header: "Finding relevant information",
|
|
8954
|
-
// sub_header: "
|
|
9095
|
+
// sub_header: "Iris is working to identify relevant information to user answer user query",
|
|
8955
9096
|
// step_status: "completed",
|
|
8956
9097
|
// },
|
|
8957
9098
|
// {
|
|
8958
9099
|
// header: "Output Generation",
|
|
8959
|
-
// sub_header: "
|
|
9100
|
+
// sub_header: "Iris is finalizing response to user query",
|
|
8960
9101
|
// step_status: "not-completed",
|
|
8961
9102
|
// },
|
|
8962
9103
|
// ];
|
|
@@ -9196,7 +9337,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
9196
9337
|
* @returns {JSX.Element} Rendered content with optional blinking cursor
|
|
9197
9338
|
*/
|
|
9198
9339
|
const renderContent = () => {
|
|
9199
|
-
return (jsxs("div", { className: classes.streamContainer, children: [jsx(StepsResponseTab, { steps: steps, stepChange: stepChange, setSteps: setSteps, stepsDone: stepsDone, setStepsDone: setStepsDone, finalStepDone: finalStepDone, setFinalStepDone: setFinalStepDone, content: content, isStreaming: isStreaming, currentMode: currentMode, questions: questions, questionsStepsMap: questionsStepsMap, stepFormDataMap: stepFormDataMap, isFormDisabled: botData?.isFormDisabled || false, streamingWidgetData: streamingWidgetData, isRetrying: isRetrying }), isRetrying && (jsx("div", { className: classes.retryContainer, children:
|
|
9340
|
+
return (jsxs("div", { className: classes.streamContainer, children: [jsx(StepsResponseTab, { steps: steps, stepChange: stepChange, setSteps: setSteps, stepsDone: stepsDone, setStepsDone: setStepsDone, finalStepDone: finalStepDone, setFinalStepDone: setFinalStepDone, content: content, isStreaming: isStreaming, currentMode: currentMode, questions: questions, questionsStepsMap: questionsStepsMap, stepFormDataMap: stepFormDataMap, isFormDisabled: botData?.isFormDisabled || false, streamingWidgetData: streamingWidgetData, isRetrying: isRetrying }), isRetrying && (jsx("div", { className: classes.retryContainer, children: jsx(TextRenderer, { text: `Auto re-trying in ${retryCountdown}s`, thinking: "" }) }))] }));
|
|
9200
9341
|
};
|
|
9201
9342
|
if (currentMode === "agent") {
|
|
9202
9343
|
return renderContent();
|
|
@@ -9467,6 +9608,12 @@ let activeTabularInstanceId = null;
|
|
|
9467
9608
|
const TabularContent = ({ steps: initialSteps, currentTabValue, children, questions: initialQuestions = [], questionsStepsMap: initialQuestionsStepsMap = {}, stepFormDataMap: initialStepFormDataMap = {}, isFormDisabled = false, sessionId: propSessionId = "" }) => {
|
|
9468
9609
|
const dispatch = useDispatch();
|
|
9469
9610
|
const stepFormStreamData = useSelector((state) => state.smartBotReducer.stepFormStreamData);
|
|
9611
|
+
const thinkingContext = useSelector((state) => state.smartBotReducer.thinkingContext);
|
|
9612
|
+
const streamStartTimeRef = useRef(thinkingContext?.streamStartTime);
|
|
9613
|
+
// Keep streamStartTime ref in sync with Redux for use in event handler closures
|
|
9614
|
+
useEffect(() => {
|
|
9615
|
+
streamStartTimeRef.current = thinkingContext?.streamStartTime;
|
|
9616
|
+
}, [thinkingContext?.streamStartTime]);
|
|
9470
9617
|
const [tabValue, setTabValue] = useState(currentTabValue);
|
|
9471
9618
|
// Local state — initialized from props, updated by SSE chunks
|
|
9472
9619
|
const [stepsState, setStepsState] = useState(() => {
|
|
@@ -9489,6 +9636,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
9489
9636
|
const [hasNewStepFormFromRestream, setHasNewStepFormFromRestream] = useState(false);
|
|
9490
9637
|
const [activeFormIntent, setActiveFormIntent] = useState(null);
|
|
9491
9638
|
const [retryCountdown, setRetryCountdown] = useState(0);
|
|
9639
|
+
const [timeoutMessage, setTimeoutMessage] = useState("");
|
|
9492
9640
|
// Stable unique instance ID for this TabularContent mount
|
|
9493
9641
|
const instanceIdRef = useRef(null);
|
|
9494
9642
|
if (instanceIdRef.current === null) {
|
|
@@ -9513,6 +9661,32 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
9513
9661
|
window.removeEventListener("stepFormStreamCompleted", handleStepFormCompleted);
|
|
9514
9662
|
};
|
|
9515
9663
|
}, []);
|
|
9664
|
+
// Switch to agent_response tab on form inactivity timeout (30 min)
|
|
9665
|
+
useEffect(() => {
|
|
9666
|
+
const handleStepFormTimeout = () => {
|
|
9667
|
+
setTimeoutMessage("This session timed out due to inactivity. Please start a new message to continue.");
|
|
9668
|
+
setStepFormSubmitted(true);
|
|
9669
|
+
setTabValue("agent_response");
|
|
9670
|
+
dispatch(setMinimizedStreamData(null));
|
|
9671
|
+
const elapsed = streamStartTimeRef.current
|
|
9672
|
+
? Math.floor((Date.now() - streamStartTimeRef.current) / 1000)
|
|
9673
|
+
: null;
|
|
9674
|
+
const mins = elapsed != null ? Math.floor(elapsed / 60) : 0;
|
|
9675
|
+
const secs = elapsed != null ? elapsed % 60 : 0;
|
|
9676
|
+
const timedOutLabel = `Worked for ${mins}m:${String(secs).padStart(2, '0')}s`;
|
|
9677
|
+
dispatch(setThinkingContext({
|
|
9678
|
+
streamStartTime: null,
|
|
9679
|
+
isStreamCompleted: true,
|
|
9680
|
+
finalElapsedSeconds: elapsed,
|
|
9681
|
+
thinkingHeaderMessage: timedOutLabel,
|
|
9682
|
+
thinkingContent: "",
|
|
9683
|
+
}));
|
|
9684
|
+
};
|
|
9685
|
+
window.addEventListener("stepFormTimeout", handleStepFormTimeout);
|
|
9686
|
+
return () => {
|
|
9687
|
+
window.removeEventListener("stepFormTimeout", handleStepFormTimeout);
|
|
9688
|
+
};
|
|
9689
|
+
}, []);
|
|
9516
9690
|
// Render a widget item from SSE data
|
|
9517
9691
|
const renderWidget = (item, index) => {
|
|
9518
9692
|
try {
|
|
@@ -9852,7 +10026,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
9852
10026
|
},
|
|
9853
10027
|
], tabPanels: [
|
|
9854
10028
|
jsx(Steps, { steps: stepsState, questions: questionsState, questionsStepsMap: questionsStepsMapState, stepFormDataMap: stepFormDataMapState, isFormDisabled: (isFormDisabled && !isRestreaming) || stepFormSubmitted, activeFormIntent: hasNewStepFormFromRestream ? activeFormIntent : null, isRestreaming: isRestreaming }),
|
|
9855
|
-
jsxs(AgentResponse, { children: [children, renderedWidgets.length > 0 && (jsx("div", { className: "restream-widget-content", children: renderedWidgets })), retryCountdown > 0 && (jsx("div", { style: { marginTop: "8px" }, children:
|
|
10029
|
+
jsxs(AgentResponse, { children: [children, renderedWidgets.length > 0 && (jsx("div", { className: "restream-widget-content", children: renderedWidgets })), retryCountdown > 0 && (jsx("div", { style: { marginTop: "8px" }, children: jsx(TextRenderer, { text: `Auto re-trying in ${retryCountdown}s`, thinking: "" }) })), timeoutMessage && (jsx("div", { style: { marginTop: "8px" }, children: jsx(TextRenderer, { text: timeoutMessage, thinking: "" }) }))] }),
|
|
9856
10030
|
], value: tabValue }) }));
|
|
9857
10031
|
};
|
|
9858
10032
|
/** Reset the active instance tracker (call when a new conversation starts from the input field) */
|
|
@@ -12902,7 +13076,7 @@ let singleConversationNewData = [
|
|
|
12902
13076
|
{
|
|
12903
13077
|
header: "Creating Plan of Action",
|
|
12904
13078
|
step_status: "completed",
|
|
12905
|
-
sub_header: "
|
|
13079
|
+
sub_header: "Iris is working to determine the best approach to answer user query",
|
|
12906
13080
|
current_intent: "List the products which are about to change status in next 10 days"
|
|
12907
13081
|
},
|
|
12908
13082
|
{
|
|
@@ -14826,7 +15000,7 @@ const SmartBot = (props) => {
|
|
|
14826
15000
|
try {
|
|
14827
15001
|
// if (localStorage.getItem("isStreaming") === "true") {
|
|
14828
15002
|
// displaySnackMessages(
|
|
14829
|
-
// "
|
|
15003
|
+
// "Iris is processing request in another tab, This request can be processed once Iris is available",
|
|
14830
15004
|
// "warning"
|
|
14831
15005
|
// );
|
|
14832
15006
|
// return;
|
|
@@ -15168,7 +15342,7 @@ const SmartBot = (props) => {
|
|
|
15168
15342
|
:
|
|
15169
15343
|
jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets, partialClose: partialClose, chatBotWidth: chatBotWidth }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
|
|
15170
15344
|
freeTextHeading: "Try adding more details :",
|
|
15171
|
-
freeTextContent: "
|
|
15345
|
+
freeTextContent: "Iris works better when you provide more context and pointed questions",
|
|
15172
15346
|
}, isStopIcon: isStop, onStopIconClick: onStopIconClick, footerText: "AI-generated responses may contain errors\u2014please verify important information", showSuggestionBanner: showSavedFilters ? false : showSuggestionBanner, onCloseSuggestionBanner: () => {
|
|
15173
15347
|
setShowSuggestionBanner(false);
|
|
15174
15348
|
}, landingScreen: isLandingScreen, onLikeClick: (params, params2) => {
|