impact-chatbot 2.3.65 → 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 +162 -25
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +162 -25
- 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.";
|
|
@@ -8981,19 +9085,19 @@ const StreamedContent = ({ botData }) => {
|
|
|
8981
9085
|
// [
|
|
8982
9086
|
// {
|
|
8983
9087
|
// header: "Finding relevant information",
|
|
8984
|
-
// sub_header: "
|
|
9088
|
+
// sub_header: "Iris is working to identify relevant information to user answer user query",
|
|
8985
9089
|
// step_status: "not-completed",
|
|
8986
9090
|
// },
|
|
8987
9091
|
// ];
|
|
8988
9092
|
// [
|
|
8989
9093
|
// {
|
|
8990
9094
|
// header: "Finding relevant information",
|
|
8991
|
-
// sub_header: "
|
|
9095
|
+
// sub_header: "Iris is working to identify relevant information to user answer user query",
|
|
8992
9096
|
// step_status: "completed",
|
|
8993
9097
|
// },
|
|
8994
9098
|
// {
|
|
8995
9099
|
// header: "Output Generation",
|
|
8996
|
-
// sub_header: "
|
|
9100
|
+
// sub_header: "Iris is finalizing response to user query",
|
|
8997
9101
|
// step_status: "not-completed",
|
|
8998
9102
|
// },
|
|
8999
9103
|
// ];
|
|
@@ -9233,7 +9337,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
9233
9337
|
* @returns {JSX.Element} Rendered content with optional blinking cursor
|
|
9234
9338
|
*/
|
|
9235
9339
|
const renderContent = () => {
|
|
9236
|
-
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: "" }) }))] }));
|
|
9237
9341
|
};
|
|
9238
9342
|
if (currentMode === "agent") {
|
|
9239
9343
|
return renderContent();
|
|
@@ -9504,6 +9608,12 @@ let activeTabularInstanceId = null;
|
|
|
9504
9608
|
const TabularContent = ({ steps: initialSteps, currentTabValue, children, questions: initialQuestions = [], questionsStepsMap: initialQuestionsStepsMap = {}, stepFormDataMap: initialStepFormDataMap = {}, isFormDisabled = false, sessionId: propSessionId = "" }) => {
|
|
9505
9609
|
const dispatch = useDispatch();
|
|
9506
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]);
|
|
9507
9617
|
const [tabValue, setTabValue] = useState(currentTabValue);
|
|
9508
9618
|
// Local state — initialized from props, updated by SSE chunks
|
|
9509
9619
|
const [stepsState, setStepsState] = useState(() => {
|
|
@@ -9526,6 +9636,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
9526
9636
|
const [hasNewStepFormFromRestream, setHasNewStepFormFromRestream] = useState(false);
|
|
9527
9637
|
const [activeFormIntent, setActiveFormIntent] = useState(null);
|
|
9528
9638
|
const [retryCountdown, setRetryCountdown] = useState(0);
|
|
9639
|
+
const [timeoutMessage, setTimeoutMessage] = useState("");
|
|
9529
9640
|
// Stable unique instance ID for this TabularContent mount
|
|
9530
9641
|
const instanceIdRef = useRef(null);
|
|
9531
9642
|
if (instanceIdRef.current === null) {
|
|
@@ -9550,6 +9661,32 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
9550
9661
|
window.removeEventListener("stepFormStreamCompleted", handleStepFormCompleted);
|
|
9551
9662
|
};
|
|
9552
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
|
+
}, []);
|
|
9553
9690
|
// Render a widget item from SSE data
|
|
9554
9691
|
const renderWidget = (item, index) => {
|
|
9555
9692
|
try {
|
|
@@ -9889,7 +10026,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
9889
10026
|
},
|
|
9890
10027
|
], tabPanels: [
|
|
9891
10028
|
jsx(Steps, { steps: stepsState, questions: questionsState, questionsStepsMap: questionsStepsMapState, stepFormDataMap: stepFormDataMapState, isFormDisabled: (isFormDisabled && !isRestreaming) || stepFormSubmitted, activeFormIntent: hasNewStepFormFromRestream ? activeFormIntent : null, isRestreaming: isRestreaming }),
|
|
9892
|
-
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: "" }) }))] }),
|
|
9893
10030
|
], value: tabValue }) }));
|
|
9894
10031
|
};
|
|
9895
10032
|
/** Reset the active instance tracker (call when a new conversation starts from the input field) */
|
|
@@ -12939,7 +13076,7 @@ let singleConversationNewData = [
|
|
|
12939
13076
|
{
|
|
12940
13077
|
header: "Creating Plan of Action",
|
|
12941
13078
|
step_status: "completed",
|
|
12942
|
-
sub_header: "
|
|
13079
|
+
sub_header: "Iris is working to determine the best approach to answer user query",
|
|
12943
13080
|
current_intent: "List the products which are about to change status in next 10 days"
|
|
12944
13081
|
},
|
|
12945
13082
|
{
|
|
@@ -14863,7 +15000,7 @@ const SmartBot = (props) => {
|
|
|
14863
15000
|
try {
|
|
14864
15001
|
// if (localStorage.getItem("isStreaming") === "true") {
|
|
14865
15002
|
// displaySnackMessages(
|
|
14866
|
-
// "
|
|
15003
|
+
// "Iris is processing request in another tab, This request can be processed once Iris is available",
|
|
14867
15004
|
// "warning"
|
|
14868
15005
|
// );
|
|
14869
15006
|
// return;
|
|
@@ -15205,7 +15342,7 @@ const SmartBot = (props) => {
|
|
|
15205
15342
|
:
|
|
15206
15343
|
jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets, partialClose: partialClose, chatBotWidth: chatBotWidth }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
|
|
15207
15344
|
freeTextHeading: "Try adding more details :",
|
|
15208
|
-
freeTextContent: "
|
|
15345
|
+
freeTextContent: "Iris works better when you provide more context and pointed questions",
|
|
15209
15346
|
}, isStopIcon: isStop, onStopIconClick: onStopIconClick, footerText: "AI-generated responses may contain errors\u2014please verify important information", showSuggestionBanner: showSavedFilters ? false : showSuggestionBanner, onCloseSuggestionBanner: () => {
|
|
15210
15347
|
setShowSuggestionBanner(false);
|
|
15211
15348
|
}, landingScreen: isLandingScreen, onLikeClick: (params, params2) => {
|