impact-chatbot 2.3.85 → 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.esm.js CHANGED
@@ -19,7 +19,7 @@ import remarkGfm from 'remark-gfm';
19
19
  import DOMPurify from 'dompurify';
20
20
  import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
21
21
  import { setSelectedFilters, setFilterConfiguration, getFilterUserConfiguration } from 'core/actions/filterAction';
22
- import { setChatbotContext, setStepFormStreamData, setMinimizedStreamData, setThinkingContext, setPersistedFormValues, clearPersistedFormValues, setCurrentAgentChatId, setHierarchyKeyValue, setChatbotFilterOptions, setSavedFilterSets } from 'core/actions/smartBotActions';
22
+ import { setThinkingContext, setChatbotContext, setStepFormStreamData, setMinimizedStreamData, setPersistedFormValues, clearPersistedFormValues, setCurrentAgentChatId, setHierarchyKeyValue, setChatbotFilterOptions, setSavedFilterSets } from 'core/actions/smartBotActions';
23
23
  import RefreshIcon from '@mui/icons-material/Refresh';
24
24
  import styled from 'styled-components';
25
25
  import { CircularProgress, Typography, Grid } from '@mui/material';
@@ -1420,31 +1420,50 @@ const ThinkinHeaderInfo = (props) => {
1420
1420
  });
1421
1421
  const { streamStartTime, isStreamCompleted, finalElapsedSeconds, thinkingHeaderMessage } = thinkingContext;
1422
1422
  const [elapsed, setElapsed] = useState(0);
1423
+ const [frozenText, setFrozenText] = useState(null);
1423
1424
  const intervalRef = useRef(null);
1424
1425
  // Once this instance sees "completed", freeze it permanently so a future
1425
1426
  // chat's streamStartTime doesn't cause it to start ticking again.
1426
1427
  const frozenRef = useRef(false);
1427
1428
  const frozenTextRef = useRef(null);
1428
- const streamStartTimeRef = useRef(null); // Track streamStartTime changes to unfreeze
1429
+ // The streamStartTime this instance latched onto. Used to detect when a
1430
+ // different stream has taken over (e.g. the user asked a new question while
1431
+ // this message's step form was still waiting for input).
1432
+ const ownStartTimeRef = useRef(null);
1433
+ /**
1434
+ * Freezes this instance permanently on a final label and elapsed value.
1435
+ */
1436
+ const freeze = (text, seconds) => {
1437
+ frozenRef.current = true;
1438
+ frozenTextRef.current = text;
1439
+ setFrozenText(text);
1440
+ setElapsed(seconds);
1441
+ };
1429
1442
  useEffect(() => {
1430
1443
  // If already frozen (stream completed), NEVER unfreeze.
1431
1444
  // This prevents a new chat's streamStartTime from restarting this timer.
1432
1445
  if (frozenRef.current)
1433
1446
  return;
1434
- // Track streamStartTime changes for non-frozen instances
1435
- if (streamStartTimeRef.current !== streamStartTime) {
1436
- streamStartTimeRef.current = streamStartTime;
1447
+ // Adopt the first non-null streamStartTime we see as this instance's own
1448
+ if (ownStartTimeRef.current === null && streamStartTime) {
1449
+ ownStartTimeRef.current = streamStartTime;
1437
1450
  }
1451
+ const ownStartTime = ownStartTimeRef.current;
1438
1452
  // Clear any existing interval
1439
1453
  if (intervalRef.current) {
1440
1454
  clearInterval(intervalRef.current);
1441
1455
  intervalRef.current = null;
1442
1456
  }
1443
1457
  if (isStreamCompleted && typeof finalElapsedSeconds === 'number') {
1444
- // Freeze this instance it will never tick again
1445
- frozenRef.current = true;
1446
- frozenTextRef.current = `Completed in ${formatElapsedTime(finalElapsedSeconds)}`;
1447
- setElapsed(finalElapsedSeconds);
1458
+ // Freeze this instance - it will never tick again
1459
+ freeze(`Completed in ${formatElapsedTime(finalElapsedSeconds)}`, finalElapsedSeconds);
1460
+ }
1461
+ else if (ownStartTime !== null && streamStartTime !== ownStartTime) {
1462
+ // A different stream has started (new question) while this one never
1463
+ // completed - typically an abandoned step form. Freeze on this
1464
+ // instance's OWN elapsed time instead of following the new stream.
1465
+ const ownElapsed = Math.floor((Date.now() - ownStartTime) / 1000);
1466
+ freeze(`Completed in ${formatElapsedTime(ownElapsed)}`, ownElapsed);
1448
1467
  }
1449
1468
  else if (streamStartTime && !isStreamCompleted) {
1450
1469
  // Live timer — update every second
@@ -1465,8 +1484,8 @@ const ThinkinHeaderInfo = (props) => {
1465
1484
  }, [streamStartTime, isStreamCompleted, finalElapsedSeconds]);
1466
1485
  // Determine display text
1467
1486
  let displayText = thinkingHeaderMessage || '';
1468
- if (frozenRef.current && frozenTextRef.current) {
1469
- displayText = frozenTextRef.current;
1487
+ if (frozenText || (frozenRef.current && frozenTextRef.current)) {
1488
+ displayText = frozenText || frozenTextRef.current;
1470
1489
  }
1471
1490
  else if (streamStartTime && !isStreamCompleted) {
1472
1491
  displayText = `Working for ${formatElapsedTime(elapsed)}`;
@@ -2460,6 +2479,20 @@ const useChatFlow = (chatDataRef, setLoader, setFlowType, setScreenName, setUser
2460
2479
  }
2461
2480
  if (data.flow_type === "agent" && data.actionType === "direct") {
2462
2481
  data.baseUrl = baseUrl;
2482
+ // Reset the timer before the request goes out (same as index.jsx
2483
+ // handleSendMessage). Without this the new ThinkinHeaderInfo mounts while
2484
+ // the previous response's "completed" state is still in Redux and freezes
2485
+ // itself on that stale elapsed time.
2486
+ // streamStartTime stays null here: processStream sets it, so a question
2487
+ // has exactly one start time (two would make the new header look like a
2488
+ // superseded one and freeze it at 0m:00s).
2489
+ dispatch(setThinkingContext({
2490
+ thinkingContent: "",
2491
+ thinkingHeaderMessage: "Working for 0m:00s",
2492
+ streamStartTime: null,
2493
+ isStreamCompleted: false,
2494
+ finalElapsedSeconds: null,
2495
+ }));
2463
2496
  prepareDataAndSendToAgent(data, false, {
2464
2497
  chatbotContext: chatbotContext,
2465
2498
  setChatbotContext: setChatbotContext,
@@ -8673,7 +8706,7 @@ const StreamedContent = ({ botData, botProps }) => {
8673
8706
  const retryTimerRef = useRef(null); // Interval ref for countdown
8674
8707
  const retryCountdownRef = useRef(0); // Non-state countdown for interval callback
8675
8708
  const thinkingContentRef = useRef("");
8676
- useSelector((state) => {
8709
+ const thinkingContext = useSelector((state) => {
8677
8710
  return state.smartBotReducer.thinkingContext;
8678
8711
  });
8679
8712
  const stepRef = useRef(_isAbortedRemount
@@ -8696,7 +8729,10 @@ const StreamedContent = ({ botData, botProps }) => {
8696
8729
  const thinkingStartTimeRef = useRef(null);
8697
8730
  const thinkingTimeFinalRef = useRef(0);
8698
8731
  const thinkingHeaderMessageRef = useRef("Working for 0m:00s");
8699
- const streamStartTimeRef = useRef(null);
8732
+ // Inherit the in-flight start time so a remount (e.g. tab switch, where
8733
+ // processStream is not re-run) keeps the original one instead of resetting.
8734
+ // Null for a fresh question - processStream sets it.
8735
+ const streamStartTimeRef = useRef(thinkingContext?.isStreamCompleted ? null : thinkingContext?.streamStartTime || null);
8700
8736
  const thinkingDoneRef = useRef(false);
8701
8737
  const thinkingStartedRef = useRef(false);
8702
8738
  const setThinkingContentRef = useRef(setThinkingContent); // Store current setThinkingContent function
@@ -15856,10 +15892,14 @@ const SmartBot = (props) => {
15856
15892
  answerMode: answerMode,
15857
15893
  };
15858
15894
  // if(!isEmpty(userInput)) {
15895
+ // Clear the previous response's completed state so the incoming
15896
+ // ThinkinHeaderInfo doesn't freeze on it. streamStartTime stays null
15897
+ // here: processStream sets it, so a question has exactly one start
15898
+ // time (two would make the new header look like a superseded one).
15859
15899
  dispatch(setThinkingContext({
15860
15900
  thinkingContent: "",
15861
15901
  thinkingHeaderMessage: "Working for 0m:00s",
15862
- streamStartTime: Date.now(),
15902
+ streamStartTime: null,
15863
15903
  isStreamCompleted: false,
15864
15904
  finalElapsedSeconds: null,
15865
15905
  }));