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.cjs.js
CHANGED
|
@@ -337,7 +337,7 @@ const useBotConfiguration = (setRefreshLoader, setEnableRefreshAction, dispatch)
|
|
|
337
337
|
*/
|
|
338
338
|
const parseResponse = (data, type, agentId = "", currentMode = "", disableTimeAndName = false, sessionId = "", utilityData = {}, inputBody = null, utilityObject = {}) => {
|
|
339
339
|
const timeString = disableTimeAndName ? "" : moment().format("DD-MM-YYYY HH:mm:ss");
|
|
340
|
-
const userName = disableTimeAndName ? "" : "
|
|
340
|
+
const userName = disableTimeAndName ? "" : "Iris";
|
|
341
341
|
switch (type || data?.type) {
|
|
342
342
|
case "text":
|
|
343
343
|
return {
|
|
@@ -1414,7 +1414,7 @@ const useAgentFlow = (dateFormat, chatDataRef, currentMode, setShowChatPlacehold
|
|
|
1414
1414
|
hasDirectActionType: false,
|
|
1415
1415
|
};
|
|
1416
1416
|
const loaderData = {
|
|
1417
|
-
userName: "
|
|
1417
|
+
userName: "Iris",
|
|
1418
1418
|
timeStamp: currentTimeString,
|
|
1419
1419
|
userType: "loader",
|
|
1420
1420
|
};
|
|
@@ -1980,7 +1980,7 @@ const useAgentFlow = (dateFormat, chatDataRef, currentMode, setShowChatPlacehold
|
|
|
1980
1980
|
const failResponseText = {
|
|
1981
1981
|
timeStamp: getCurrentDateTimeString(),
|
|
1982
1982
|
userType: "bot",
|
|
1983
|
-
userName: "
|
|
1983
|
+
userName: "Iris",
|
|
1984
1984
|
bodyText: error?.response?.data?.data?.error?.response
|
|
1985
1985
|
? error?.response?.data?.data?.error?.response
|
|
1986
1986
|
: "Sorry, chatbot is not available now",
|
|
@@ -2224,7 +2224,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2224
2224
|
return {
|
|
2225
2225
|
timeStamp: timeString,
|
|
2226
2226
|
userType: "bot",
|
|
2227
|
-
userName: "
|
|
2227
|
+
userName: "Iris",
|
|
2228
2228
|
headerTitle: headerTitle,
|
|
2229
2229
|
bodyType: "chips",
|
|
2230
2230
|
bodyText: screens.map((screen) => ({
|
|
@@ -2278,7 +2278,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2278
2278
|
flow_type: flowType,
|
|
2279
2279
|
};
|
|
2280
2280
|
const loaderData = {
|
|
2281
|
-
userName: "
|
|
2281
|
+
userName: "Iris",
|
|
2282
2282
|
timeStamp: currentTimeString,
|
|
2283
2283
|
userType: "loader",
|
|
2284
2284
|
};
|
|
@@ -2312,7 +2312,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2312
2312
|
const failResponseText = {
|
|
2313
2313
|
timeStamp: getCurrentDateTimeString(),
|
|
2314
2314
|
userType: "bot",
|
|
2315
|
-
userName: "
|
|
2315
|
+
userName: "Iris",
|
|
2316
2316
|
bodyText: options.data.data.message,
|
|
2317
2317
|
enableLikes: false,
|
|
2318
2318
|
headerTitle: "",
|
|
@@ -2331,7 +2331,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2331
2331
|
const failResponseText = {
|
|
2332
2332
|
timeStamp: getCurrentDateTimeString(),
|
|
2333
2333
|
userType: "bot",
|
|
2334
|
-
userName: "
|
|
2334
|
+
userName: "Iris",
|
|
2335
2335
|
bodyText: "Failed to fetch user screens. Please try again later.",
|
|
2336
2336
|
headerTitle: "",
|
|
2337
2337
|
enableLikes: false,
|
|
@@ -2403,7 +2403,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2403
2403
|
hasDirectActionType: fetchQuestions,
|
|
2404
2404
|
};
|
|
2405
2405
|
const loaderData = {
|
|
2406
|
-
userName: "
|
|
2406
|
+
userName: "Iris",
|
|
2407
2407
|
timeStamp: currentTimeString,
|
|
2408
2408
|
userType: "loader",
|
|
2409
2409
|
};
|
|
@@ -2523,7 +2523,7 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
|
|
|
2523
2523
|
const failResponseText = {
|
|
2524
2524
|
timeStamp: getCurrentDateTimeString(),
|
|
2525
2525
|
userType: "bot",
|
|
2526
|
-
userName: "
|
|
2526
|
+
userName: "Iris",
|
|
2527
2527
|
bodyText: error?.response?.data?.data?.error?.response
|
|
2528
2528
|
? error?.response?.data?.data?.error?.response
|
|
2529
2529
|
: "Sorry, chatbot is not available now",
|
|
@@ -2734,10 +2734,10 @@ const useChatSession = (chatDataRef, setFlowType, setScreenName, setUserInput, s
|
|
|
2734
2734
|
{
|
|
2735
2735
|
timeStamp: getCurrentDateTimeString(),
|
|
2736
2736
|
userType: "bot",
|
|
2737
|
-
userName: "
|
|
2737
|
+
userName: "Iris",
|
|
2738
2738
|
headerTitle: `Hi ${getUserName()}!`,
|
|
2739
2739
|
bodyType: "text",
|
|
2740
|
-
bodyText: `I am
|
|
2740
|
+
bodyText: `I am Iris, your virtual assistant. I am here to help you on anything you are looking for in IA Smart Platform`,
|
|
2741
2741
|
},
|
|
2742
2742
|
];
|
|
2743
2743
|
// chatDataRef.current[currentMode].conversations[
|
|
@@ -4903,7 +4903,7 @@ const ChatPlaceholder = (props) => {
|
|
|
4903
4903
|
agentId: card.agentId || card.id
|
|
4904
4904
|
}));
|
|
4905
4905
|
const dataToMap = legacyAgentScreen || displayQuestions ? transformedCardList : rectangleData;
|
|
4906
|
-
return (jsxRuntime.jsxs("div", { className: classes.placeholderContainer, children: [jsxRuntime.jsx("div", { className: classes.centerIconContainer, children: jsxRuntime.jsx(SvgCenter3D, { className: classes.centerIcon }) }), jsxRuntime.jsxs("div", { className: classes.headingContainer, children: [jsxRuntime.jsx(material.Typography, { variant: "h1", className: classes.heading, children: "
|
|
4906
|
+
return (jsxRuntime.jsxs("div", { className: classes.placeholderContainer, children: [jsxRuntime.jsx("div", { className: classes.centerIconContainer, children: jsxRuntime.jsx(SvgCenter3D, { className: classes.centerIcon }) }), jsxRuntime.jsxs("div", { className: classes.headingContainer, children: [jsxRuntime.jsx(material.Typography, { variant: "h1", className: classes.heading, children: "Iris's Capabilities" }), jsxRuntime.jsx("span", { className: classes.alphaTag, children: "Beta" })] }), jsxRuntime.jsx(material.Typography, { variant: "body1", className: classes.headingHelperText, children: "Discover potential issues & opportunities Iris can help you with!" }), jsxRuntime.jsx("div", { className: classes.rectanglesContainer, children: dataToMap.map((item, index) => (jsxRuntime.jsx(Rectangle, { type: item.type, icon: item.icon, title: item.title, description: item.description, onClick: () => handleRectangleClick(item?.agentId, item?.title), hoverable: legacyAgentScreen || displayQuestions }, index))) })] }));
|
|
4907
4907
|
};
|
|
4908
4908
|
|
|
4909
4909
|
const dateFormat = "DD-MM-YYYY HH:mm:ss";
|
|
@@ -7149,15 +7149,43 @@ const StepFormContent = ({ formData, messageIndex = 0, isFormDisabled = false, s
|
|
|
7149
7149
|
const chatbotFilterOptions = reactRedux.useSelector((state) => state.smartBotReducer.chatbotFilterOptions);
|
|
7150
7150
|
const dimensionHierarchies = reactRedux.useSelector((state) => state.userRoleManagementService?.dimensionHierarchies);
|
|
7151
7151
|
const [isFormSubmitted, setIsFormSubmitted] = React.useState(false);
|
|
7152
|
+
const [isTimedOut, setIsTimedOut] = React.useState(false);
|
|
7153
|
+
const timeoutRef = React.useRef(null);
|
|
7154
|
+
// 30-minute inactivity timeout: disable form and switch to agent_response tab
|
|
7155
|
+
const FORM_TIMEOUT_MS = 30 * 60 * 1000;
|
|
7156
|
+
React.useEffect(() => {
|
|
7157
|
+
if (isFormDisabled || isFormSubmitted || isTimedOut)
|
|
7158
|
+
return;
|
|
7159
|
+
const startTime = Date.now();
|
|
7160
|
+
timeoutRef.current = setTimeout(() => {
|
|
7161
|
+
setIsTimedOut(true);
|
|
7162
|
+
const elapsedSeconds = Math.floor((Date.now() - startTime) / 1000);
|
|
7163
|
+
window.dispatchEvent(new CustomEvent("stepFormTimeout", { detail: { elapsedSeconds } }));
|
|
7164
|
+
}, FORM_TIMEOUT_MS);
|
|
7165
|
+
return () => {
|
|
7166
|
+
if (timeoutRef.current) {
|
|
7167
|
+
clearTimeout(timeoutRef.current);
|
|
7168
|
+
timeoutRef.current = null;
|
|
7169
|
+
}
|
|
7170
|
+
};
|
|
7171
|
+
}, [isFormDisabled, isFormSubmitted, isTimedOut]);
|
|
7172
|
+
// Clear timeout when form is submitted
|
|
7173
|
+
React.useEffect(() => {
|
|
7174
|
+
if (isFormSubmitted && timeoutRef.current) {
|
|
7175
|
+
clearTimeout(timeoutRef.current);
|
|
7176
|
+
timeoutRef.current = null;
|
|
7177
|
+
}
|
|
7178
|
+
}, [isFormSubmitted]);
|
|
7152
7179
|
React.useEffect(() => {
|
|
7153
7180
|
if (stepFormStreamData?.status === "streaming_start") {
|
|
7154
7181
|
setIsFormSubmitted(true);
|
|
7155
7182
|
}
|
|
7156
7183
|
}, [stepFormStreamData]);
|
|
7157
|
-
// Reset isFormSubmitted when parent signals the form should be enabled (new step_form from restream)
|
|
7184
|
+
// Reset isFormSubmitted and isTimedOut when parent signals the form should be enabled (new step_form from restream)
|
|
7158
7185
|
React.useEffect(() => {
|
|
7159
7186
|
if (!isFormDisabled) {
|
|
7160
7187
|
setIsFormSubmitted(false);
|
|
7188
|
+
setIsTimedOut(false);
|
|
7161
7189
|
}
|
|
7162
7190
|
}, [isFormDisabled]);
|
|
7163
7191
|
const [isFilterSetOpen, setIsFilterSetOpen] = React.useState(false);
|
|
@@ -7228,8 +7256,8 @@ const StepFormContent = ({ formData, messageIndex = 0, isFormDisabled = false, s
|
|
|
7228
7256
|
return val && (Array.isArray(val) ? val.length > 0 : !!val);
|
|
7229
7257
|
});
|
|
7230
7258
|
}, [persistedFormValues, messageIndex]);
|
|
7231
|
-
const formFieldsDisabled = isFormDisabled || isFilterSelected || isFormSubmitted;
|
|
7232
|
-
const savedFilterDisabled = isFormDisabled || isFormFieldUsed || isFormSubmitted;
|
|
7259
|
+
const formFieldsDisabled = isFormDisabled || isFilterSelected || isFormSubmitted || isTimedOut;
|
|
7260
|
+
const savedFilterDisabled = isFormDisabled || isFormFieldUsed || isFormSubmitted || isTimedOut;
|
|
7233
7261
|
const requiredFieldsFilled = React.useMemo(() => {
|
|
7234
7262
|
if (!formData || !Array.isArray(formData))
|
|
7235
7263
|
return false;
|
|
@@ -7817,7 +7845,40 @@ const AgentResponse$1 = (props) => {
|
|
|
7817
7845
|
|
|
7818
7846
|
const StepsResponseTab = (props) => {
|
|
7819
7847
|
const { steps, setSteps, stepsDone, setStepsDone, finalStepDone, setFinalStepDone, content, isStreaming, stepChange, currentMode, questions, questionsStepsMap, stepFormDataMap, isFormDisabled, streamingWidgetData, isRetrying, } = props;
|
|
7848
|
+
const dispatch = reactRedux.useDispatch();
|
|
7849
|
+
const thinkingContext = reactRedux.useSelector((state) => state.smartBotReducer.thinkingContext);
|
|
7850
|
+
const streamStartTimeRef = React.useRef(thinkingContext?.streamStartTime);
|
|
7851
|
+
// Keep streamStartTime ref in sync with Redux for use in event handler closures
|
|
7852
|
+
React.useEffect(() => {
|
|
7853
|
+
streamStartTimeRef.current = thinkingContext?.streamStartTime;
|
|
7854
|
+
}, [thinkingContext?.streamStartTime]);
|
|
7820
7855
|
const [tabValue, setTabValue] = React.useState("steps");
|
|
7856
|
+
const [timeoutMessage, setTimeoutMessage] = React.useState("");
|
|
7857
|
+
// Switch to agent_response tab on form inactivity timeout (30 min)
|
|
7858
|
+
React.useEffect(() => {
|
|
7859
|
+
const handleStepFormTimeout = () => {
|
|
7860
|
+
setTimeoutMessage("This session timed out due to inactivity. Please start a new message to continue.");
|
|
7861
|
+
setTabValue("agent_response");
|
|
7862
|
+
dispatch(smartBotActions.setMinimizedStreamData(null));
|
|
7863
|
+
const elapsed = streamStartTimeRef.current
|
|
7864
|
+
? Math.floor((Date.now() - streamStartTimeRef.current) / 1000)
|
|
7865
|
+
: null;
|
|
7866
|
+
const mins = elapsed != null ? Math.floor(elapsed / 60) : 0;
|
|
7867
|
+
const secs = elapsed != null ? elapsed % 60 : 0;
|
|
7868
|
+
const timedOutLabel = `Worked for ${mins}m:${String(secs).padStart(2, '0')}s`;
|
|
7869
|
+
dispatch(smartBotActions.setThinkingContext({
|
|
7870
|
+
streamStartTime: null,
|
|
7871
|
+
isStreamCompleted: true,
|
|
7872
|
+
finalElapsedSeconds: elapsed,
|
|
7873
|
+
thinkingHeaderMessage: timedOutLabel,
|
|
7874
|
+
thinkingContent: "",
|
|
7875
|
+
}));
|
|
7876
|
+
};
|
|
7877
|
+
window.addEventListener("stepFormTimeout", handleStepFormTimeout);
|
|
7878
|
+
return () => {
|
|
7879
|
+
window.removeEventListener("stepFormTimeout", handleStepFormTimeout);
|
|
7880
|
+
};
|
|
7881
|
+
}, []);
|
|
7821
7882
|
// When retry countdown starts, switch to agent_response to show it.
|
|
7822
7883
|
// When retry actually fires (isRetrying goes false + isStreaming goes true), switch back to steps.
|
|
7823
7884
|
React.useEffect(() => {
|
|
@@ -7846,7 +7907,7 @@ const StepsResponseTab = (props) => {
|
|
|
7846
7907
|
},
|
|
7847
7908
|
], tabPanels: [
|
|
7848
7909
|
jsxRuntime.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 }),
|
|
7849
|
-
jsxRuntime.jsx(AgentResponse$1, { content: content, isStreaming: isStreaming, streamingWidgetData: streamingWidgetData }),
|
|
7910
|
+
jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(AgentResponse$1, { content: content, isStreaming: isStreaming, streamingWidgetData: streamingWidgetData }), timeoutMessage && (jsxRuntime.jsx("div", { style: { marginTop: "8px", padding: "0 8px" }, children: jsxRuntime.jsx(TextRenderer, { text: timeoutMessage, thinking: "" }) }))] }),
|
|
7850
7911
|
], value: tabValue }) }));
|
|
7851
7912
|
};
|
|
7852
7913
|
|
|
@@ -8674,6 +8735,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
8674
8735
|
// Check if this is a user-initiated abort (should not trigger retry)
|
|
8675
8736
|
const isUserAbort = event.reason === "Network request aborted";
|
|
8676
8737
|
event.statusCode === 503;
|
|
8738
|
+
const isAgentUnavailable = event.statusCode === 502 || event.statusCode === 404;
|
|
8677
8739
|
if (isThinking) {
|
|
8678
8740
|
setIsThinking(false);
|
|
8679
8741
|
const endTime = Date.now();
|
|
@@ -8684,8 +8746,50 @@ const StreamedContent = ({ botData }) => {
|
|
|
8684
8746
|
thinkingStartTimeRef.current = finalThinkingTime;
|
|
8685
8747
|
messageToStoreRef.current.chatData.thinkingResponse.thinkingTime = finalThinkingTime;
|
|
8686
8748
|
}
|
|
8749
|
+
// Agent unavailable (502/404) — show specific message, no retry
|
|
8750
|
+
if (isAgentUnavailable) {
|
|
8751
|
+
setWasStreamingAborted(true);
|
|
8752
|
+
wasStreamingAbortedRef.current = true;
|
|
8753
|
+
const currentSteps = stepRef.current;
|
|
8754
|
+
if (currentSteps.length > 0) {
|
|
8755
|
+
const lastStep = currentSteps[currentSteps.length - 1];
|
|
8756
|
+
if (lastStep.step_status === "not-completed") {
|
|
8757
|
+
lastStep.step_status = "completed";
|
|
8758
|
+
}
|
|
8759
|
+
stepRef.current = [...currentSteps];
|
|
8760
|
+
setSteps([...currentSteps]);
|
|
8761
|
+
}
|
|
8762
|
+
const agentUnavailableMessage = "Agent isn't available right now. Please contact your administrator or try again later.";
|
|
8763
|
+
const hasExistingWidgetsOnUnavail = messageToStoreRef.current.appendedData &&
|
|
8764
|
+
(isArray(messageToStoreRef.current.appendedData)
|
|
8765
|
+
? messageToStoreRef.current.appendedData.length > 0
|
|
8766
|
+
: Object.keys(messageToStoreRef.current.appendedData).length > 0);
|
|
8767
|
+
if (hasExistingWidgetsOnUnavail) {
|
|
8768
|
+
const errorWidget = { type: "text", response: agentUnavailableMessage };
|
|
8769
|
+
if (isArray(messageToStoreRef.current.appendedData)) {
|
|
8770
|
+
messageToStoreRef.current.appendedData.push(errorWidget);
|
|
8771
|
+
}
|
|
8772
|
+
else {
|
|
8773
|
+
messageToStoreRef.current.appendedData = [messageToStoreRef.current.appendedData, errorWidget];
|
|
8774
|
+
}
|
|
8775
|
+
}
|
|
8776
|
+
else {
|
|
8777
|
+
messageToStoreRef.current.chatData.response = agentUnavailableMessage;
|
|
8778
|
+
}
|
|
8779
|
+
setContent(agentUnavailableMessage);
|
|
8780
|
+
dispatch(smartBotActions.setMinimizedStreamData({
|
|
8781
|
+
isStreaming: false,
|
|
8782
|
+
stepHeader: questionsRef.current[questionsRef.current.length - 1] || "Agent unavailable",
|
|
8783
|
+
stepSubHeader: "Connection closed",
|
|
8784
|
+
stepStatus: "completed",
|
|
8785
|
+
streamStartTime: streamStartTimeRef.current,
|
|
8786
|
+
actionCount: questionsRef.current.length || 1,
|
|
8787
|
+
}));
|
|
8788
|
+
setStepsDone(true);
|
|
8789
|
+
setIsStreamingDone(true);
|
|
8790
|
+
}
|
|
8687
8791
|
// Check if we can auto-retry (abrupt close or 503, but not user abort)
|
|
8688
|
-
if (!isUserAbort && retryCountRef.current < MAX_RETRY_COUNT) {
|
|
8792
|
+
else if (!isUserAbort && retryCountRef.current < MAX_RETRY_COUNT) {
|
|
8689
8793
|
// Still have retries left — start countdown instead of showing final error
|
|
8690
8794
|
setStepsDone(true); // Switch to agent_response tab to show countdown
|
|
8691
8795
|
const retryMessage = "The service is temporarily unavailable because of an unusual load. Please wait a moment and try again.";
|
|
@@ -8705,8 +8809,26 @@ const StreamedContent = ({ botData }) => {
|
|
|
8705
8809
|
stepRef.current = [...currentSteps];
|
|
8706
8810
|
setSteps([...currentSteps]);
|
|
8707
8811
|
}
|
|
8708
|
-
|
|
8709
|
-
|
|
8812
|
+
// Append the error message at the bottom of any existing content.
|
|
8813
|
+
// If widgets already exist in appendedData, append as the last widget
|
|
8814
|
+
// so it renders AFTER the already-received content (not at the top).
|
|
8815
|
+
const finalMessage = "The service is temporarily unavailable because of an unusual load. Please wait a moment and try again.";
|
|
8816
|
+
const hasExistingWidgetsOnErr = messageToStoreRef.current.appendedData &&
|
|
8817
|
+
(isArray(messageToStoreRef.current.appendedData)
|
|
8818
|
+
? messageToStoreRef.current.appendedData.length > 0
|
|
8819
|
+
: Object.keys(messageToStoreRef.current.appendedData).length > 0);
|
|
8820
|
+
if (hasExistingWidgetsOnErr) {
|
|
8821
|
+
const errorWidget = { type: "text", response: finalMessage };
|
|
8822
|
+
if (isArray(messageToStoreRef.current.appendedData)) {
|
|
8823
|
+
messageToStoreRef.current.appendedData.push(errorWidget);
|
|
8824
|
+
}
|
|
8825
|
+
else {
|
|
8826
|
+
messageToStoreRef.current.appendedData = [messageToStoreRef.current.appendedData, errorWidget];
|
|
8827
|
+
}
|
|
8828
|
+
}
|
|
8829
|
+
else {
|
|
8830
|
+
messageToStoreRef.current.chatData.response = finalMessage;
|
|
8831
|
+
}
|
|
8710
8832
|
setContent(finalMessage);
|
|
8711
8833
|
dispatch(smartBotActions.setMinimizedStreamData({
|
|
8712
8834
|
isStreaming: false,
|
|
@@ -8748,9 +8870,10 @@ const StreamedContent = ({ botData }) => {
|
|
|
8748
8870
|
startRetryCountdown();
|
|
8749
8871
|
}
|
|
8750
8872
|
else {
|
|
8751
|
-
// Retries exhausted — show final
|
|
8873
|
+
// Retries exhausted — show final message
|
|
8752
8874
|
setWasStreamingAborted(true);
|
|
8753
8875
|
wasStreamingAbortedRef.current = true;
|
|
8876
|
+
// Mark the last in-progress step as completed
|
|
8754
8877
|
const currentSteps = stepRef.current;
|
|
8755
8878
|
if (currentSteps.length > 0) {
|
|
8756
8879
|
const lastStep = currentSteps[currentSteps.length - 1];
|
|
@@ -8760,8 +8883,26 @@ const StreamedContent = ({ botData }) => {
|
|
|
8760
8883
|
stepRef.current = [...currentSteps];
|
|
8761
8884
|
setSteps([...currentSteps]);
|
|
8762
8885
|
}
|
|
8763
|
-
|
|
8764
|
-
|
|
8886
|
+
// Append the error message at the bottom of any existing content.
|
|
8887
|
+
// If widgets already exist in appendedData, append as the last widget
|
|
8888
|
+
// so it renders AFTER the already-received content (not at the top).
|
|
8889
|
+
const finalMessage = "The service is temporarily unavailable because of an unusual load. Please wait a moment and try again.";
|
|
8890
|
+
const hasExistingWidgets = messageToStoreRef.current.appendedData &&
|
|
8891
|
+
(isArray(messageToStoreRef.current.appendedData)
|
|
8892
|
+
? messageToStoreRef.current.appendedData.length > 0
|
|
8893
|
+
: Object.keys(messageToStoreRef.current.appendedData).length > 0);
|
|
8894
|
+
if (hasExistingWidgets) {
|
|
8895
|
+
const errorWidget = { type: "text", response: finalMessage };
|
|
8896
|
+
if (isArray(messageToStoreRef.current.appendedData)) {
|
|
8897
|
+
messageToStoreRef.current.appendedData.push(errorWidget);
|
|
8898
|
+
}
|
|
8899
|
+
else {
|
|
8900
|
+
messageToStoreRef.current.appendedData = [messageToStoreRef.current.appendedData, errorWidget];
|
|
8901
|
+
}
|
|
8902
|
+
}
|
|
8903
|
+
else {
|
|
8904
|
+
messageToStoreRef.current.chatData.response = finalMessage;
|
|
8905
|
+
}
|
|
8765
8906
|
setContent(finalMessage);
|
|
8766
8907
|
dispatch(smartBotActions.setMinimizedStreamData({
|
|
8767
8908
|
isStreaming: false,
|
|
@@ -8966,19 +9107,19 @@ const StreamedContent = ({ botData }) => {
|
|
|
8966
9107
|
// [
|
|
8967
9108
|
// {
|
|
8968
9109
|
// header: "Finding relevant information",
|
|
8969
|
-
// sub_header: "
|
|
9110
|
+
// sub_header: "Iris is working to identify relevant information to user answer user query",
|
|
8970
9111
|
// step_status: "not-completed",
|
|
8971
9112
|
// },
|
|
8972
9113
|
// ];
|
|
8973
9114
|
// [
|
|
8974
9115
|
// {
|
|
8975
9116
|
// header: "Finding relevant information",
|
|
8976
|
-
// sub_header: "
|
|
9117
|
+
// sub_header: "Iris is working to identify relevant information to user answer user query",
|
|
8977
9118
|
// step_status: "completed",
|
|
8978
9119
|
// },
|
|
8979
9120
|
// {
|
|
8980
9121
|
// header: "Output Generation",
|
|
8981
|
-
// sub_header: "
|
|
9122
|
+
// sub_header: "Iris is finalizing response to user query",
|
|
8982
9123
|
// step_status: "not-completed",
|
|
8983
9124
|
// },
|
|
8984
9125
|
// ];
|
|
@@ -9218,7 +9359,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
9218
9359
|
* @returns {JSX.Element} Rendered content with optional blinking cursor
|
|
9219
9360
|
*/
|
|
9220
9361
|
const renderContent = () => {
|
|
9221
|
-
return (jsxRuntime.jsxs("div", { className: classes.streamContainer, children: [jsxRuntime.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 && (jsxRuntime.jsx("div", { className: classes.retryContainer, children: jsxRuntime.
|
|
9362
|
+
return (jsxRuntime.jsxs("div", { className: classes.streamContainer, children: [jsxRuntime.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 && (jsxRuntime.jsx("div", { className: classes.retryContainer, children: jsxRuntime.jsx(TextRenderer, { text: `Auto re-trying in ${retryCountdown}s`, thinking: "" }) }))] }));
|
|
9222
9363
|
};
|
|
9223
9364
|
if (currentMode === "agent") {
|
|
9224
9365
|
return renderContent();
|
|
@@ -9489,6 +9630,12 @@ let activeTabularInstanceId = null;
|
|
|
9489
9630
|
const TabularContent = ({ steps: initialSteps, currentTabValue, children, questions: initialQuestions = [], questionsStepsMap: initialQuestionsStepsMap = {}, stepFormDataMap: initialStepFormDataMap = {}, isFormDisabled = false, sessionId: propSessionId = "" }) => {
|
|
9490
9631
|
const dispatch = reactRedux.useDispatch();
|
|
9491
9632
|
const stepFormStreamData = reactRedux.useSelector((state) => state.smartBotReducer.stepFormStreamData);
|
|
9633
|
+
const thinkingContext = reactRedux.useSelector((state) => state.smartBotReducer.thinkingContext);
|
|
9634
|
+
const streamStartTimeRef = React.useRef(thinkingContext?.streamStartTime);
|
|
9635
|
+
// Keep streamStartTime ref in sync with Redux for use in event handler closures
|
|
9636
|
+
React.useEffect(() => {
|
|
9637
|
+
streamStartTimeRef.current = thinkingContext?.streamStartTime;
|
|
9638
|
+
}, [thinkingContext?.streamStartTime]);
|
|
9492
9639
|
const [tabValue, setTabValue] = React.useState(currentTabValue);
|
|
9493
9640
|
// Local state — initialized from props, updated by SSE chunks
|
|
9494
9641
|
const [stepsState, setStepsState] = React.useState(() => {
|
|
@@ -9511,6 +9658,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
9511
9658
|
const [hasNewStepFormFromRestream, setHasNewStepFormFromRestream] = React.useState(false);
|
|
9512
9659
|
const [activeFormIntent, setActiveFormIntent] = React.useState(null);
|
|
9513
9660
|
const [retryCountdown, setRetryCountdown] = React.useState(0);
|
|
9661
|
+
const [timeoutMessage, setTimeoutMessage] = React.useState("");
|
|
9514
9662
|
// Stable unique instance ID for this TabularContent mount
|
|
9515
9663
|
const instanceIdRef = React.useRef(null);
|
|
9516
9664
|
if (instanceIdRef.current === null) {
|
|
@@ -9535,6 +9683,32 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
9535
9683
|
window.removeEventListener("stepFormStreamCompleted", handleStepFormCompleted);
|
|
9536
9684
|
};
|
|
9537
9685
|
}, []);
|
|
9686
|
+
// Switch to agent_response tab on form inactivity timeout (30 min)
|
|
9687
|
+
React.useEffect(() => {
|
|
9688
|
+
const handleStepFormTimeout = () => {
|
|
9689
|
+
setTimeoutMessage("This session timed out due to inactivity. Please start a new message to continue.");
|
|
9690
|
+
setStepFormSubmitted(true);
|
|
9691
|
+
setTabValue("agent_response");
|
|
9692
|
+
dispatch(smartBotActions.setMinimizedStreamData(null));
|
|
9693
|
+
const elapsed = streamStartTimeRef.current
|
|
9694
|
+
? Math.floor((Date.now() - streamStartTimeRef.current) / 1000)
|
|
9695
|
+
: null;
|
|
9696
|
+
const mins = elapsed != null ? Math.floor(elapsed / 60) : 0;
|
|
9697
|
+
const secs = elapsed != null ? elapsed % 60 : 0;
|
|
9698
|
+
const timedOutLabel = `Worked for ${mins}m:${String(secs).padStart(2, '0')}s`;
|
|
9699
|
+
dispatch(smartBotActions.setThinkingContext({
|
|
9700
|
+
streamStartTime: null,
|
|
9701
|
+
isStreamCompleted: true,
|
|
9702
|
+
finalElapsedSeconds: elapsed,
|
|
9703
|
+
thinkingHeaderMessage: timedOutLabel,
|
|
9704
|
+
thinkingContent: "",
|
|
9705
|
+
}));
|
|
9706
|
+
};
|
|
9707
|
+
window.addEventListener("stepFormTimeout", handleStepFormTimeout);
|
|
9708
|
+
return () => {
|
|
9709
|
+
window.removeEventListener("stepFormTimeout", handleStepFormTimeout);
|
|
9710
|
+
};
|
|
9711
|
+
}, []);
|
|
9538
9712
|
// Render a widget item from SSE data
|
|
9539
9713
|
const renderWidget = (item, index) => {
|
|
9540
9714
|
try {
|
|
@@ -9874,7 +10048,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
9874
10048
|
},
|
|
9875
10049
|
], tabPanels: [
|
|
9876
10050
|
jsxRuntime.jsx(Steps, { steps: stepsState, questions: questionsState, questionsStepsMap: questionsStepsMapState, stepFormDataMap: stepFormDataMapState, isFormDisabled: (isFormDisabled && !isRestreaming) || stepFormSubmitted, activeFormIntent: hasNewStepFormFromRestream ? activeFormIntent : null, isRestreaming: isRestreaming }),
|
|
9877
|
-
jsxRuntime.jsxs(AgentResponse, { children: [children, renderedWidgets.length > 0 && (jsxRuntime.jsx("div", { className: "restream-widget-content", children: renderedWidgets })), retryCountdown > 0 && (jsxRuntime.jsx("div", { style: { marginTop: "8px" }, children: jsxRuntime.
|
|
10051
|
+
jsxRuntime.jsxs(AgentResponse, { children: [children, renderedWidgets.length > 0 && (jsxRuntime.jsx("div", { className: "restream-widget-content", children: renderedWidgets })), retryCountdown > 0 && (jsxRuntime.jsx("div", { style: { marginTop: "8px" }, children: jsxRuntime.jsx(TextRenderer, { text: `Auto re-trying in ${retryCountdown}s`, thinking: "" }) })), timeoutMessage && (jsxRuntime.jsx("div", { style: { marginTop: "8px" }, children: jsxRuntime.jsx(TextRenderer, { text: timeoutMessage, thinking: "" }) }))] }),
|
|
9878
10052
|
], value: tabValue }) }));
|
|
9879
10053
|
};
|
|
9880
10054
|
/** Reset the active instance tracker (call when a new conversation starts from the input field) */
|
|
@@ -12924,7 +13098,7 @@ let singleConversationNewData = [
|
|
|
12924
13098
|
{
|
|
12925
13099
|
header: "Creating Plan of Action",
|
|
12926
13100
|
step_status: "completed",
|
|
12927
|
-
sub_header: "
|
|
13101
|
+
sub_header: "Iris is working to determine the best approach to answer user query",
|
|
12928
13102
|
current_intent: "List the products which are about to change status in next 10 days"
|
|
12929
13103
|
},
|
|
12930
13104
|
{
|
|
@@ -14848,7 +15022,7 @@ const SmartBot = (props) => {
|
|
|
14848
15022
|
try {
|
|
14849
15023
|
// if (localStorage.getItem("isStreaming") === "true") {
|
|
14850
15024
|
// displaySnackMessages(
|
|
14851
|
-
// "
|
|
15025
|
+
// "Iris is processing request in another tab, This request can be processed once Iris is available",
|
|
14852
15026
|
// "warning"
|
|
14853
15027
|
// );
|
|
14854
15028
|
// return;
|
|
@@ -15190,7 +15364,7 @@ const SmartBot = (props) => {
|
|
|
15190
15364
|
:
|
|
15191
15365
|
jsxRuntime.jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets, partialClose: partialClose, chatBotWidth: chatBotWidth }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
|
|
15192
15366
|
freeTextHeading: "Try adding more details :",
|
|
15193
|
-
freeTextContent: "
|
|
15367
|
+
freeTextContent: "Iris works better when you provide more context and pointed questions",
|
|
15194
15368
|
}, isStopIcon: isStop, onStopIconClick: onStopIconClick, footerText: "AI-generated responses may contain errors\u2014please verify important information", showSuggestionBanner: showSavedFilters ? false : showSuggestionBanner, onCloseSuggestionBanner: () => {
|
|
15195
15369
|
setShowSuggestionBanner(false);
|
|
15196
15370
|
}, landingScreen: isLandingScreen, onLikeClick: (params, params2) => {
|