impact-chatbot 2.3.75 → 2.3.77

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
@@ -5195,6 +5195,12 @@ const sseevent = (message, messageToStoreRef) => {
5195
5195
  };
5196
5196
  }
5197
5197
  }
5198
+ // Strip large debugging metadata that is never used for rendering.
5199
+ // The meta field contains text_chunks, supplemental_chunks, image_ids
5200
+ // arrays that accumulate in memory and contribute to OOM crashes.
5201
+ if (parsedData?.meta) {
5202
+ delete parsedData.meta;
5203
+ }
5198
5204
  if (messageToStoreRef.current.currentMode === "agent" &&
5199
5205
  (parsedData?.chat_id || parsedData?.session_id)) {
5200
5206
  messageToStoreRef.current.uniqueChatId = parsedData?.chat_id
@@ -5693,6 +5699,10 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
5693
5699
  stepFormStreamControl.uniqueChatId = data?.chat_id ? data.chat_id : "";
5694
5700
  // Clear sessionStorage so stale session_id isn't picked up by future non-init calls
5695
5701
  sessionStorage.setItem("stepForm_sessionId", "");
5702
+ // Notify SmartBot to update its initValue/sessionId state
5703
+ window.dispatchEvent(new CustomEvent("stepFormInitStateUpdate", {
5704
+ detail: { initValue: true, sessionId: "", uniqueChatId: data?.chat_id || "" },
5705
+ }));
5696
5706
  }
5697
5707
  // Stream ended — dispatch all collected chunks at once
5698
5708
  stepFormStreamControl.isStreaming = false;
@@ -8086,7 +8096,7 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
8086
8096
  }, children: jsx(ProgressBarItem$1, { question: "Thinking", questionSteps: [{ header: "", sub_header: "", step_status: "not-completed" }], isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled }) }))] }));
8087
8097
  };
8088
8098
 
8089
- const renderWidgetItem = (item, index) => {
8099
+ const renderWidgetItem = (item, index, isFormDisabled) => {
8090
8100
  try {
8091
8101
  const parsedData = parseResponse(item, item.type, "", "", true);
8092
8102
  if (!parsedData)
@@ -8099,6 +8109,22 @@ const renderWidgetItem = (item, index) => {
8099
8109
  return jsx(TableContent, { bodyText: parsedData.bodyText }, key);
8100
8110
  case "graph":
8101
8111
  return jsx(GraphContent, { bodyText: parsedData.bodyText }, key);
8112
+ case "radio":
8113
+ return jsx(RadioContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8114
+ case "checkbox":
8115
+ return jsx(CheckboxContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8116
+ case "select":
8117
+ return jsx(SelectContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8118
+ case "slider":
8119
+ return jsx(SliderContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8120
+ case "button":
8121
+ return jsx(ButtonContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8122
+ case "input":
8123
+ return jsx(InputContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8124
+ case "datePicker":
8125
+ return jsx(DatePickerContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8126
+ case "dateRangePicker":
8127
+ return jsx(DateRangePickerContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8102
8128
  default:
8103
8129
  return null;
8104
8130
  }
@@ -8109,11 +8135,11 @@ const renderWidgetItem = (item, index) => {
8109
8135
  }
8110
8136
  };
8111
8137
  const AgentResponse$1 = (props) => {
8112
- const { content, isStreaming, streamingWidgetData = [] } = props;
8138
+ const { content, isStreaming, streamingWidgetData = [], isFormDisabled = false } = props;
8113
8139
  const classes = useStyles$6();
8114
8140
  const chatClasses = useStyles$9();
8115
8141
  const renderedWidgets = streamingWidgetData
8116
- .map((item, index) => renderWidgetItem(item, index))
8142
+ .map((item, index) => renderWidgetItem(item, index, isFormDisabled))
8117
8143
  .filter(Boolean);
8118
8144
  return (jsxs("div", { className: chatClasses.agentResponseContainer, children: [content ? (jsxs(Typography, { className: chatClasses.bodyTextStyling, children: [jsx(TextRenderer, { text: content }), isStreaming && renderedWidgets.length === 0 && jsx("span", { className: classes.cursor })] })) : null, renderedWidgets.length > 0 && (jsx("div", { className: "streaming-widget-content", children: renderedWidgets })), isStreaming && (renderedWidgets.length > 0 || !content) && (jsx("span", { className: classes.cursor }))] }));
8119
8145
  };
@@ -8184,7 +8210,7 @@ const StepsResponseTab = (props) => {
8184
8210
  },
8185
8211
  ], tabPanels: [
8186
8212
  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 || isTimedOut }),
8187
- 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: "" }) }))] }),
8213
+ jsxs(Fragment, { children: [jsx(AgentResponse$1, { content: content, isStreaming: isStreaming, streamingWidgetData: streamingWidgetData, isFormDisabled: isFormDisabled || isTimedOut }), timeoutMessage && (jsx("div", { style: { marginTop: "8px", padding: "0 8px" }, children: jsx(TextRenderer, { text: timeoutMessage, thinking: "" }) }))] }),
8188
8214
  ], value: tabValue }) }));
8189
8215
  };
8190
8216
 
@@ -9329,6 +9355,16 @@ const StreamedContent = ({ botData }) => {
9329
9355
  ];
9330
9356
  botData.utilityObject.setInitValue(messageToStoreRef.current.initValue);
9331
9357
  botData.utilityObject.setSessionId(messageToStoreRef.current.sessionId);
9358
+ // Also update currentSessionId via event so the send button uses the correct session_id
9359
+ if (messageToStoreRef.current.status === "completed" || messageToStoreRef.current.status === "follow-up") {
9360
+ window.dispatchEvent(new CustomEvent("stepFormInitStateUpdate", {
9361
+ detail: {
9362
+ initValue: messageToStoreRef.current.initValue,
9363
+ sessionId: messageToStoreRef.current.sessionId,
9364
+ uniqueChatId: messageToStoreRef.current.uniqueChatId,
9365
+ },
9366
+ }));
9367
+ }
9332
9368
  botData.utilityObject.setAdditionalArgs(!isEmpty(messageToStoreRef.current.additionalArgs)
9333
9369
  ? messageToStoreRef.current.additionalArgs
9334
9370
  : {});
@@ -9407,10 +9443,10 @@ const StreamedContent = ({ botData }) => {
9407
9443
  processResponse(response, botData.inputBody, currentMode, botData.utilityObject.customChatConfig, {
9408
9444
  newChatData: chatDataInfoRef,
9409
9445
  isTabEnabled: true,
9410
- steps: cloneDeep(stepRef.current),
9446
+ steps: stepRef.current.map(s => ({ ...s })),
9411
9447
  currentTabValue: (stepsDone && !hasStepFormWidgets) ? "agent_response" : "steps",
9412
- questions: cloneDeep(questionsRef.current),
9413
- questionsStepsMap: cloneDeep(questionsStepsMapRef.current),
9448
+ questions: [...questionsRef.current],
9449
+ questionsStepsMap: { ...questionsStepsMapRef.current },
9414
9450
  stepFormDataMap: { ...stepFormDataMapRef.current },
9415
9451
  }, activeConversationId);
9416
9452
  // [
@@ -9515,10 +9551,10 @@ const StreamedContent = ({ botData }) => {
9515
9551
  processResponse(response, botData.inputBody, currentMode, botData.utilityObject.customChatConfig, {
9516
9552
  newChatData: chatDataInfoRef,
9517
9553
  isTabEnabled: true,
9518
- steps: cloneDeep(stepRef.current),
9554
+ steps: stepRef.current.map(s => ({ ...s })),
9519
9555
  currentTabValue: stepsDone ? "agent_response" : "steps",
9520
- questions: cloneDeep(questionsRef.current),
9521
- questionsStepsMap: cloneDeep(questionsStepsMapRef.current),
9556
+ questions: [...questionsRef.current],
9557
+ questionsStepsMap: { ...questionsStepsMapRef.current },
9522
9558
  stepFormDataMap: { ...stepFormDataMapRef.current },
9523
9559
  }, activeConversationId);
9524
9560
  }
@@ -10090,6 +10126,22 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
10090
10126
  return jsx(TableContent, { bodyText: parsedData.bodyText }, key);
10091
10127
  case "graph":
10092
10128
  return jsx(GraphContent, { bodyText: parsedData.bodyText }, key);
10129
+ case "radio":
10130
+ return jsx(RadioContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
10131
+ case "checkbox":
10132
+ return jsx(CheckboxContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
10133
+ case "select":
10134
+ return jsx(SelectContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
10135
+ case "slider":
10136
+ return jsx(SliderContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
10137
+ case "button":
10138
+ return jsx(ButtonContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
10139
+ case "input":
10140
+ return jsx(InputContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
10141
+ case "datePicker":
10142
+ return jsx(DatePickerContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
10143
+ case "dateRangePicker":
10144
+ return jsx(DateRangePickerContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
10093
10145
  default:
10094
10146
  return null;
10095
10147
  }
@@ -10390,6 +10442,29 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
10390
10442
  setQuestionsStepsMapState(cloneDeep(newQuestionsStepsMap));
10391
10443
  setStepFormDataMapState(cloneDeep(newStepFormDataMap));
10392
10444
  if (newWidgets.length > 0) {
10445
+ // If widget data contains form components (radio, select, checkbox, etc.),
10446
+ // append a Submit button so the user can submit their selection
10447
+ const formTypes = ["radio", "select", "checkbox", "slider", "input", "datePicker", "dateRangePicker"];
10448
+ const hasFormWidget = newWidgets.some((item) => formTypes.includes(item?.type));
10449
+ const hasStepForm = chunks.some((c) => c.status === "step_form");
10450
+ if (hasFormWidget && !hasStepForm) {
10451
+ const sendButton = document.getElementById("chat-input-send-button");
10452
+ newWidgets.push({
10453
+ type: "button",
10454
+ data: {
10455
+ message: "",
10456
+ buttons: [
10457
+ {
10458
+ label: "Submit",
10459
+ variant: "primary",
10460
+ size: "medium",
10461
+ disabled: false,
10462
+ onClick: () => sendButton?.click(),
10463
+ },
10464
+ ],
10465
+ },
10466
+ });
10467
+ }
10393
10468
  // Replace (not append) to avoid duplicates from real-time widget_chunk dispatches
10394
10469
  setWidgetContent(newWidgets);
10395
10470
  }
@@ -14771,11 +14846,25 @@ const SmartBot = (props) => {
14771
14846
  console.error("Error updating timestamp after step form stream:", e);
14772
14847
  }
14773
14848
  };
14849
+ // Update SmartBot-level initValue/sessionId when ButtonContent's stream receives completed/follow-up
14850
+ const handleStepFormInitStateUpdate = (e) => {
14851
+ const { initValue: newInitValue, sessionId: newSessionId, uniqueChatId: newChatId } = e.detail || {};
14852
+ if (newInitValue !== undefined)
14853
+ setInitValue(newInitValue);
14854
+ if (newSessionId !== undefined) {
14855
+ setSessionId(newSessionId);
14856
+ setCurrentSessionId(newSessionId);
14857
+ }
14858
+ if (newChatId !== undefined)
14859
+ setUniqueChatId(newChatId);
14860
+ };
14774
14861
  window.addEventListener("stepFormStreamStart", handleStepFormStreamStart);
14775
14862
  window.addEventListener("stepFormStreamEnd", handleStepFormStreamEnd);
14863
+ window.addEventListener("stepFormInitStateUpdate", handleStepFormInitStateUpdate);
14776
14864
  return () => {
14777
14865
  window.removeEventListener("stepFormStreamStart", handleStepFormStreamStart);
14778
14866
  window.removeEventListener("stepFormStreamEnd", handleStepFormStreamEnd);
14867
+ window.removeEventListener("stepFormInitStateUpdate", handleStepFormInitStateUpdate);
14779
14868
  };
14780
14869
  }, []);
14781
14870
  const fetchCustomBotConfigurations = async () => {
@@ -15297,7 +15386,7 @@ const SmartBot = (props) => {
15297
15386
  let newChatData = chatDataState?.[currentMode]?.conversations?.[activeConversationId]?.messages;
15298
15387
  let newChatDataLength = newChatData?.length - 1;
15299
15388
  if (newChatDataLength) {
15300
- chatDataInfoRef.current[currentMode].conversations[activeConversationId].messages[chatDataInfoRefLength - 1] = cloneDeep(newChatData?.[newChatDataLength]);
15389
+ chatDataInfoRef.current[currentMode].conversations[activeConversationId].messages[chatDataInfoRefLength - 1] = { ...newChatData?.[newChatDataLength] };
15301
15390
  }
15302
15391
  }
15303
15392
  // let chatDataForReference = JSON.stringify(
@@ -15334,15 +15423,11 @@ const SmartBot = (props) => {
15334
15423
  // ;
15335
15424
  message.isFormDisabled = index !== lastBotMessageIndex;
15336
15425
  message.messageIndex = index;
15337
- let originalUtilityObject = message.utilityObject;
15338
- let originalThinkingResponse = message.thinkingResponse;
15339
- let newMessage = cloneDeep(message);
15340
- if (originalUtilityObject) {
15341
- newMessage.utilityObject = originalUtilityObject;
15342
- }
15343
- if (originalThinkingResponse) {
15344
- newMessage.thinkingResponse = originalThinkingResponse;
15345
- }
15426
+ // Shallow copy — avoids cloneDeep which causes OOM on large
15427
+ // bodyText (images, widget data, meta objects).
15428
+ // utilityObject, thinkingResponse, and bodyText are preserved
15429
+ // by reference since child components only read them.
15430
+ let newMessage = { ...message };
15346
15431
  message.jsx = (jsx(BotMessage, { botData: newMessage, state: loadingState, handleLikeDislike: handleLikeDislike, props: properties }));
15347
15432
  let actualProps = {
15348
15433
  botData: newMessage,
@@ -15355,17 +15440,20 @@ const SmartBot = (props) => {
15355
15440
  // message.enableLikes = true;
15356
15441
  }
15357
15442
  });
15358
- // Create a deep clone and remove JSX properties to avoid circular references
15359
- let newChat = cloneDeep(chatDataInfoRef?.current[currentMode]);
15360
- // Restore thinkingResponse (may contain JSX components like ThinkinHeaderInfo)
15361
- // which cloneDeep serializes into plain objects
15362
- const originalMessages = chatDataInfoRef?.current[currentMode]?.conversations?.[activeConversationId]?.messages || [];
15363
- const clonedMessages = newChat?.conversations?.[activeConversationId]?.messages || [];
15364
- originalMessages.forEach((origMsg, idx) => {
15365
- if (origMsg.thinkingResponse && clonedMessages[idx]) {
15366
- clonedMessages[idx].thinkingResponse = origMsg.thinkingResponse;
15367
- }
15368
- });
15443
+ // Shallow-clone the conversation structure to trigger React re-render
15444
+ // without deep-cloning large message payloads (which caused OOM crashes).
15445
+ const modeData = chatDataInfoRef?.current[currentMode];
15446
+ const convMessages = modeData?.conversations?.[activeConversationId]?.messages || [];
15447
+ let newChat = {
15448
+ ...modeData,
15449
+ conversations: {
15450
+ ...modeData?.conversations,
15451
+ [activeConversationId]: {
15452
+ ...modeData?.conversations?.[activeConversationId],
15453
+ messages: convMessages.map(msg => ({ ...msg })),
15454
+ },
15455
+ },
15456
+ };
15369
15457
  setConversation(newChat);
15370
15458
  }
15371
15459
  else if (showModal) {