impact-chatbot 2.3.42 → 2.3.47

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.
@@ -5,6 +5,8 @@ export declare const stepFormStreamControl: {
5
5
  chatId: string;
6
6
  agentId: string;
7
7
  baseUrl: string;
8
+ initValue: boolean;
9
+ uniqueChatId: string;
8
10
  };
9
11
  declare const ButtonContent: ({ bodyText, isFormDisabled, isStepFormSubmit, isFormValid }: {
10
12
  bodyText: any;
package/dist/index.cjs.js CHANGED
@@ -5095,6 +5095,17 @@ const sseevent = (message, messageToStoreRef) => {
5095
5095
  messageToStoreRef.current.chatData.response =
5096
5096
  messageToStoreRef.current.chatData.response +
5097
5097
  "There is an error, please reach out to IA with this use case.";
5098
+ // Still process completed/follow-up status even on error chunks
5099
+ // so that initValue is set correctly and dummyButton is suppressed
5100
+ if (parsedData?.status === "completed" ||
5101
+ parsedData?.status === "follow-up") {
5102
+ messageToStoreRef.current.initValue = true;
5103
+ messageToStoreRef.current.sessionId = "";
5104
+ messageToStoreRef.current.uniqueChatId = parsedData?.chat_id
5105
+ ? parsedData.chat_id
5106
+ : "";
5107
+ messageToStoreRef.current.status = parsedData?.status;
5108
+ }
5098
5109
  return new MessageEvent(type, { data: data });
5099
5110
  }
5100
5111
  if (parsedData?.status === "thinking") {
@@ -5295,6 +5306,9 @@ const stepFormStreamControl = {
5295
5306
  chatId: "",
5296
5307
  agentId: "",
5297
5308
  baseUrl: "",
5309
+ // Completed/follow-up state — persists across ButtonContent remounts
5310
+ initValue: false,
5311
+ uniqueChatId: "",
5298
5312
  };
5299
5313
  const useStyles$5 = styles.makeStyles((theme) => ({
5300
5314
  buttonContainer: {
@@ -5357,8 +5371,15 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
5357
5371
  };
5358
5372
  const callInitApiStream = (userInput) => {
5359
5373
  // Prefer module-level values (set synchronously by StreamedContent), fall back to sessionStorage
5360
- const sessionId = stepFormStreamControl.sessionId || sessionStorage.getItem("stepForm_sessionId") || "";
5361
- const chatId = stepFormStreamControl.chatId || sessionStorage.getItem("stepForm_chatId") || "";
5374
+ // If a previous completed/follow-up response updated the state, use those values.
5375
+ // Read from module-level stepFormStreamControl (survives remounts) instead of local messageStoreRef.
5376
+ const hasCompletedState = stepFormStreamControl.initValue === true;
5377
+ const sessionId = hasCompletedState
5378
+ ? (stepFormStreamControl.sessionId ?? "")
5379
+ : (stepFormStreamControl.sessionId || sessionStorage.getItem("stepForm_sessionId") || "");
5380
+ const chatId = hasCompletedState
5381
+ ? (stepFormStreamControl.uniqueChatId ?? "")
5382
+ : (stepFormStreamControl.chatId || sessionStorage.getItem("stepForm_chatId") || "");
5362
5383
  const agentId = stepFormStreamControl.agentId || sessionStorage.getItem("stepForm_agentId") || "";
5363
5384
  const baseUrl = stepFormStreamControl.baseUrl || sessionStorage.getItem("stepForm_baseUrl") || "";
5364
5385
  const payload = {
@@ -5366,9 +5387,14 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
5366
5387
  session_id: sessionId,
5367
5388
  chat_id: chatId,
5368
5389
  user_input: userInput,
5369
- init: false,
5390
+ init: hasCompletedState ? true : false,
5370
5391
  delay: 0.3,
5371
5392
  };
5393
+ // Reset the flag so subsequent calls don't re-use stale completed state
5394
+ if (hasCompletedState) {
5395
+ messageStoreRef.current.initValue = false;
5396
+ stepFormStreamControl.initValue = false;
5397
+ }
5372
5398
  const endPoint = baseUrl
5373
5399
  ? `${api.BASE_API}${baseUrl}/chatbot/agent/init`
5374
5400
  : `${api.BASE_API}/core/chatbot/agent/init`;
@@ -5410,6 +5436,10 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
5410
5436
  console.log("[ButtonContent] SSE chunk:", data);
5411
5437
  if (data?.status === "step" || data?.status === "step_form" || data?.status === "questions" || data?.status === "thinking" || data?.status === "widget") {
5412
5438
  chunksRef.push(data);
5439
+ // Dispatch widget chunks immediately for real-time rendering
5440
+ if (data?.status === "widget") {
5441
+ dispatch(smartBotActions.setStepFormStreamData({ status: "widget_chunk", chunks: [data] }));
5442
+ }
5413
5443
  // If this chunk also carries [DONE], dispatch collected chunks now
5414
5444
  if (data?.message === "[DONE]") {
5415
5445
  stepFormStreamControl.isStreaming = false;
@@ -5418,13 +5448,25 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
5418
5448
  dispatch(smartBotActions.setStepFormStreamData({ status: "done", chunks: [...chunksRef] }));
5419
5449
  }
5420
5450
  }
5421
- else if (data?.status === "completed" || data?.message === "[DONE]") {
5451
+ else if (data?.status === "completed" || data?.status === "follow-up" || data?.message === "[DONE]") {
5452
+ // Update messageStoreRef the same way AxiosEventSource does for completed/follow-up
5453
+ if (data?.status === "completed" || data?.status === "follow-up") {
5454
+ messageStoreRef.current.initValue = true;
5455
+ messageStoreRef.current.sessionId = "";
5456
+ messageStoreRef.current.uniqueChatId = data?.chat_id ? data.chat_id : "";
5457
+ // Also persist on module-level object so it survives ButtonContent remounts
5458
+ stepFormStreamControl.initValue = true;
5459
+ stepFormStreamControl.sessionId = "";
5460
+ stepFormStreamControl.uniqueChatId = data?.chat_id ? data.chat_id : "";
5461
+ }
5422
5462
  // Stream ended — dispatch all collected chunks at once
5423
5463
  stepFormStreamControl.isStreaming = false;
5424
5464
  stepFormStreamControl.abort = null;
5425
5465
  window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
5426
- // Signal tab switch to agent_response when status is "completed"
5427
- if (data?.status === "completed") {
5466
+ // Signal tab switch to agent_response when status is "completed",
5467
+ // but only if the response doesn't contain a new step_form that needs user interaction
5468
+ const hasStepForm = chunksRef.some((c) => c.status === "step_form");
5469
+ if (data?.status === "completed" && !hasStepForm) {
5428
5470
  window.dispatchEvent(new CustomEvent("stepFormStreamCompleted"));
5429
5471
  }
5430
5472
  dispatch(smartBotActions.setStepFormStreamData({ status: "done", chunks: [...chunksRef] }));
@@ -5790,6 +5832,15 @@ const SliderContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
5790
5832
  return (jsxRuntime.jsx("div", { style: { width: "100%", marginTop: "10px" }, children: jsxRuntime.jsx(impactUiV3.Slider, { header: header, headerOrientation: headerOrentiation, inputPosition: inputPosition, label: label, max: max, min: min, required: required, disabled: disabled || isFormDisabled, onChange: (e) => handleChange(e), value: sliderValue }) }));
5791
5833
  };
5792
5834
 
5835
+ const INITIAL_DISPLAY_COUNT = 100;
5836
+ const LOAD_MORE_COUNT = 100;
5837
+ const formatOption = (option) => ({
5838
+ ...option,
5839
+ label: replaceSpecialCharacter(option.label.toString()),
5840
+ });
5841
+ const formatSlice = (options, start, end) => {
5842
+ return options.slice(start, end).map(formatOption);
5843
+ };
5793
5844
  const SelectContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
5794
5845
  const formKey = `${messageIndex}_${bodyText?.paramName}`;
5795
5846
  const { header, inputPosition, labelOrientation, label, options, isRequired, isDisabled, isMulti, paramName } = bodyText;
@@ -5799,6 +5850,7 @@ const SelectContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
5799
5850
  const [currentSelectedOptions, setCurrentSelectedOptions] = React.useState(persistedFormValues?.[formKey] || []);
5800
5851
  const [isAllSelected, setIsAllSelected] = React.useState(false);
5801
5852
  const [initialOptions, setInitialOptions] = React.useState([]);
5853
+ const allOptionsRef = React.useRef([]);
5802
5854
  const chatbotContext = reactRedux.useSelector((state) => state.smartBotReducer.chatbotContext);
5803
5855
  const heirarchyKeyValuePairs = reactRedux.useSelector((state) => state.smartBotReducer.heirarchyKeyValuePairs);
5804
5856
  const dispatch = reactRedux.useDispatch();
@@ -5837,19 +5889,46 @@ const SelectContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
5837
5889
  }
5838
5890
  }, [persistedFormValues, formKey]);
5839
5891
  React.useEffect(() => {
5840
- let formattedOptions = options.map((option) => {
5841
- return {
5842
- ...option,
5843
- label: replaceSpecialCharacter(option.label.toString()),
5844
- };
5845
- });
5846
- setInitialOptions(formattedOptions);
5847
- setCurrentOptions(formattedOptions);
5892
+ allOptionsRef.current = options;
5893
+ const initialSlice = formatSlice(options, 0, INITIAL_DISPLAY_COUNT);
5894
+ setInitialOptions(initialSlice);
5895
+ setCurrentOptions(initialSlice);
5848
5896
  }, []);
5849
5897
  return (jsxRuntime.jsx("div", { style: { width: "100%", marginTop: "10px" }, children: jsxRuntime.jsx(impactUiV3.Select, { currentOptions: currentOptions, setCurrentOptions: setCurrentOptions, label: heirarchyKeyValuePairs[paramName] || label, labelOrientation: labelOrientation,
5850
5898
  // inputPosition={inputPosition}
5851
5899
  // header={header}
5852
- isRequired: isRequired, isDisabled: isDisabled || isFormDisabled, handleChange: (selected) => onChange(selected), isCloseWhenClickOutside: true, setIsOpen: setIsOpen, isOpen: isOpen, selectedOptions: currentSelectedOptions, setSelectedOptions: setCurrentSelectedOptions, initialOptions: initialOptions, isMulti: isMulti, isSelectAll: isAllSelected, setIsSelectAll: setIsAllSelected, toggleSelectAll: true, isWithSearch: isMulti ? true : false }) }));
5900
+ isRequired: isRequired, isDisabled: isDisabled || isFormDisabled, handleChange: (selected) => onChange(selected), isCloseWhenClickOutside: true, setIsOpen: setIsOpen, isOpen: isOpen, selectedOptions: currentSelectedOptions, setSelectedOptions: setCurrentSelectedOptions, initialOptions: initialOptions, isMulti: isMulti, isSelectAll: isAllSelected, setIsSelectAll: setIsAllSelected, toggleSelectAll: true, isWithSearch: isMulti ? true : false, onMenuScrollToBottom: () => {
5901
+ const allRaw = allOptionsRef.current;
5902
+ if (allRaw.length > 0 && currentOptions.length < allRaw.length) {
5903
+ const nextCount = Math.min(currentOptions.length + LOAD_MORE_COUNT, allRaw.length);
5904
+ const newBatch = formatSlice(allRaw, currentOptions.length, nextCount);
5905
+ const nextOptions = [...currentOptions, ...newBatch];
5906
+ setCurrentOptions(nextOptions);
5907
+ setInitialOptions(nextOptions);
5908
+ if (isAllSelected) {
5909
+ setCurrentSelectedOptions(nextOptions);
5910
+ }
5911
+ }
5912
+ }, onSelectAll: (e) => {
5913
+ if (e && e.target.checked) {
5914
+ setCurrentSelectedOptions([...currentOptions]);
5915
+ setIsAllSelected(true);
5916
+ const allValues = allOptionsRef.current.map((opt) => opt.value);
5917
+ chatbotContext[bodyText?.paramName] = {
5918
+ ...chatbotContext?.[bodyText?.paramName],
5919
+ [bodyText?.paramName]: allValues,
5920
+ updated: true,
5921
+ };
5922
+ dispatch(smartBotActions.setChatbotContext(chatbotContext));
5923
+ dispatch(smartBotActions.setPersistedFormValues({ [formKey]: currentOptions }));
5924
+ }
5925
+ else {
5926
+ setCurrentSelectedOptions([]);
5927
+ setIsAllSelected(false);
5928
+ }
5929
+ }, customPlaceholderAfterSelect: isAllSelected && allOptionsRef.current.length > 0
5930
+ ? allOptionsRef.current.length
5931
+ : null }) }));
5853
5932
  };
5854
5933
 
5855
5934
  const DatePickerContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
@@ -6497,10 +6576,8 @@ const getQuestionStatus$1 = (questionSteps) => {
6497
6576
  /**
6498
6577
  * Renders a single progress bar item (main point + sub-items)
6499
6578
  */
6500
- const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData, showSavedFilters = true, isFormDisabled, isRestreaming = false, onAllSubItemsAnimated = undefined }) => {
6501
- const baseStatus = getQuestionStatus$1(questionSteps);
6502
- // When restreaming and this is the last item, show as in-progress
6503
- const status = (isRestreaming && isLast) ? "in-progress" : baseStatus;
6579
+ const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData, showSavedFilters = true, isFormDisabled, onAllSubItemsAnimated = undefined }) => {
6580
+ const status = getQuestionStatus$1(questionSteps);
6504
6581
  const animatedCountRef = React.useRef(0);
6505
6582
  const [isExpanded, setIsExpanded] = React.useState(true);
6506
6583
  const dotClass = status === "completed"
@@ -6544,8 +6621,14 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
6544
6621
  const lastQuestionCompleted = lastQuestionSteps &&
6545
6622
  lastQuestionSteps.length > 0 &&
6546
6623
  lastQuestionSteps.every((s) => s.step_status === "completed");
6624
+ const hasStepFormData = Object.keys(stepFormDataMap).length > 0;
6547
6625
  React.useEffect(() => {
6548
6626
  if (done) {
6627
+ // Don't auto-switch to agent_response tab when there's a step form pending user interaction
6628
+ if (hasStepFormData) {
6629
+ setFinalStepDone(true);
6630
+ return;
6631
+ }
6549
6632
  if (!finalStepDone) {
6550
6633
  if (currentMode === "navigation") {
6551
6634
  let updatedSteps = steps.map((step) => ({
@@ -6595,7 +6678,7 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
6595
6678
  step_status: "not-completed",
6596
6679
  },
6597
6680
  ];
6598
- return (jsxRuntime.jsx("div", { className: classes.progressBarContainer, children: jsxRuntime.jsx(ProgressBarItem$1, { question: fallbackQuestion, questionSteps: fallbackSteps, isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled, showSavedFilters: true }) }));
6681
+ return (jsxRuntime.jsx("div", { className: classes.progressBarContainer, children: jsxRuntime.jsx(ProgressBarItem$1, { question: fallbackQuestion, questionSteps: fallbackSteps, isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled }) }));
6599
6682
  }
6600
6683
  return (jsxRuntime.jsxs("div", { className: classes.progressBarContainer, children: [questions.map((question, index) => {
6601
6684
  const questionData = questionsStepsMap[question];
@@ -6618,17 +6701,40 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
6618
6701
  }, children: jsxRuntime.jsx(ProgressBarItem$1, { question: "Thinking", questionSteps: [{ header: "", sub_header: "", step_status: "not-completed" }], isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled }) }))] }));
6619
6702
  };
6620
6703
 
6704
+ const renderWidgetItem = (item, index) => {
6705
+ try {
6706
+ const parsedData = parseResponse(item, item.type, "", "", true);
6707
+ if (!parsedData)
6708
+ return null;
6709
+ const key = `streaming-widget-${index}`;
6710
+ switch (parsedData.bodyType) {
6711
+ case "text":
6712
+ return jsxRuntime.jsx(TextContent, { bodyText: parsedData.bodyText, botData: parsedData }, key);
6713
+ case "table":
6714
+ return jsxRuntime.jsx(TableContent, { bodyText: parsedData.bodyText }, key);
6715
+ case "graph":
6716
+ return jsxRuntime.jsx(GraphContent, { bodyText: parsedData.bodyText }, key);
6717
+ default:
6718
+ return null;
6719
+ }
6720
+ }
6721
+ catch (e) {
6722
+ console.error("[AgentResponse] renderWidgetItem error:", e);
6723
+ return null;
6724
+ }
6725
+ };
6621
6726
  const AgentResponse$1 = (props) => {
6622
- const { content, isStreaming } = props;
6727
+ const { content, isStreaming, streamingWidgetData = [] } = props;
6623
6728
  const classes = useStyles$4();
6624
6729
  const chatClasses = useStyles$7();
6625
- return (jsxRuntime.jsx("div", { className: chatClasses.agentResponseContainer, children: content ? (jsxRuntime.jsxs(material.Typography, { className: chatClasses.bodyTextStyling, children: [jsxRuntime.jsx(TextRenderer, { text: content }), isStreaming && jsxRuntime.jsx("span", { className: classes.cursor })] })) : (
6626
- // Show cursor even when no content yet
6627
- isStreaming && jsxRuntime.jsx("span", { className: classes.cursor })) }));
6730
+ const renderedWidgets = streamingWidgetData
6731
+ .map((item, index) => renderWidgetItem(item, index))
6732
+ .filter(Boolean);
6733
+ return (jsxRuntime.jsxs("div", { className: chatClasses.agentResponseContainer, children: [content ? (jsxRuntime.jsxs(material.Typography, { className: chatClasses.bodyTextStyling, children: [jsxRuntime.jsx(TextRenderer, { text: content }), isStreaming && renderedWidgets.length === 0 && jsxRuntime.jsx("span", { className: classes.cursor })] })) : null, renderedWidgets.length > 0 && (jsxRuntime.jsx("div", { className: "streaming-widget-content", children: renderedWidgets })), isStreaming && (renderedWidgets.length > 0 || !content) && (jsxRuntime.jsx("span", { className: classes.cursor }))] }));
6628
6734
  };
6629
6735
 
6630
6736
  const StepsResponseTab = (props) => {
6631
- const { steps, setSteps, stepsDone, setStepsDone, finalStepDone, setFinalStepDone, content, isStreaming, stepChange, currentMode, questions, questionsStepsMap, stepFormDataMap, isFormDisabled, } = props;
6737
+ const { steps, setSteps, stepsDone, setStepsDone, finalStepDone, setFinalStepDone, content, isStreaming, stepChange, currentMode, questions, questionsStepsMap, stepFormDataMap, isFormDisabled, streamingWidgetData, } = props;
6632
6738
  const [tabValue, setTabValue] = React.useState("steps");
6633
6739
  const handleChangeTabValue = (_event, newValue) => {
6634
6740
  setTabValue(newValue);
@@ -6646,7 +6752,7 @@ const StepsResponseTab = (props) => {
6646
6752
  },
6647
6753
  ], tabPanels: [
6648
6754
  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 }),
6649
- jsxRuntime.jsx(AgentResponse$1, { content: content, isStreaming: isStreaming }),
6755
+ jsxRuntime.jsx(AgentResponse$1, { content: content, isStreaming: isStreaming, streamingWidgetData: streamingWidgetData }),
6650
6756
  ], value: tabValue }) }));
6651
6757
  };
6652
6758
 
@@ -6696,6 +6802,7 @@ const StreamedContent = ({ botData }) => {
6696
6802
  // const [thinkingContent, setThinkingContent] = useState("");
6697
6803
  const [thinkDone, setThinkDone] = React.useState(false);
6698
6804
  const [isStreaming, setIsStreaming] = React.useState(true);
6805
+ const [streamingWidgetData, setStreamingWidgetData] = React.useState([]);
6699
6806
  const [thinkingStarted, setThinkingStarted] = React.useState(false);
6700
6807
  const [isStreamingDone, setIsStreamingDone] = React.useState(false);
6701
6808
  const [isThinking, setIsThinking] = React.useState(false);
@@ -6870,7 +6977,7 @@ const StreamedContent = ({ botData }) => {
6870
6977
  }));
6871
6978
  return;
6872
6979
  }
6873
- if (data?.message || data?.status === "step" || data?.status === "step_form" || data?.status === "thinking" || data?.status === "questions") {
6980
+ if (data?.message || data?.status === "step" || data?.status === "step_form" || data?.status === "thinking" || data?.status === "questions" || data?.status === "widget") {
6874
6981
  if (data.status === "questions") {
6875
6982
  const incomingQuestions = data.widget_data?.[0]?.questions || [];
6876
6983
  questionsRef.current = incomingQuestions;
@@ -6983,6 +7090,15 @@ const StreamedContent = ({ botData }) => {
6983
7090
  : [data.widget_data];
6984
7091
  const currentIntent = data.current_intent || formWidgetData?.[0]?.current_intent;
6985
7092
  if (currentIntent) {
7093
+ // Auto-create question/intent entry if no prior step chunk created it
7094
+ if (!questionsStepsMapRef.current[currentIntent]) {
7095
+ questionsStepsMapRef.current[currentIntent] = [];
7096
+ if (!questionsRef.current.includes(currentIntent)) {
7097
+ questionsRef.current = [...questionsRef.current, currentIntent];
7098
+ setQuestions([...questionsRef.current]);
7099
+ }
7100
+ setQuestionsStepsMap(lodash.cloneDeep(questionsStepsMapRef.current));
7101
+ }
6986
7102
  const sendButton = document.getElementById("chat-input-send-button");
6987
7103
  const stepFormSubmitButton = {
6988
7104
  type: "button",
@@ -7003,7 +7119,7 @@ const StreamedContent = ({ botData }) => {
7003
7119
  widgets: [...formWidgetData, stepFormSubmitButton],
7004
7120
  showSavedFilters: data.show_saved_filters !== false,
7005
7121
  };
7006
- setStepFormDataMap(lodash.cloneDeep(stepFormDataMapRef.current));
7122
+ setStepFormDataMap({ ...stepFormDataMapRef.current });
7007
7123
  }
7008
7124
  setStepChange((prev) => !prev);
7009
7125
  // Persist IDs immediately when step_form arrives (AxiosEventSource already set them)
@@ -7022,12 +7138,20 @@ const StreamedContent = ({ botData }) => {
7022
7138
  stepFormStreamControl.baseUrl = _burl;
7023
7139
  // If this is the [DONE] chunk, mark streaming as complete
7024
7140
  if (data.message === "[DONE]") {
7141
+ setStepsDone(true);
7025
7142
  setIsStreamingDone(true);
7026
7143
  const doneState = streamStateMap.get(streamKey);
7027
7144
  if (doneState)
7028
7145
  doneState.completed = true;
7029
7146
  }
7030
7147
  }
7148
+ else if (data.status === "widget") {
7149
+ // Render widget data immediately as it arrives during streaming
7150
+ const widgetItems = isArray(data.widget_data)
7151
+ ? data.widget_data
7152
+ : [data.widget_data];
7153
+ setStreamingWidgetData((prev) => [...prev, ...widgetItems]);
7154
+ }
7031
7155
  else if (data.message !== "[DONE]") {
7032
7156
  if (!thinkingDoneRef?.current && currentMode === "agent") {
7033
7157
  thinkingDoneRef.current = true;
@@ -7110,6 +7234,13 @@ const StreamedContent = ({ botData }) => {
7110
7234
  const store = messageToStoreRef.current;
7111
7235
  // Restore accumulated content
7112
7236
  setContent(store.chatData?.response || "");
7237
+ // Restore widget data received so far
7238
+ if (isArray(store.appendedData) && store.appendedData.length > 0) {
7239
+ setStreamingWidgetData(store.appendedData);
7240
+ }
7241
+ else if (store.appendedData && !isArray(store.appendedData) && Object.keys(store.appendedData).length > 0) {
7242
+ setStreamingWidgetData([store.appendedData]);
7243
+ }
7113
7244
  // Restore thinking state
7114
7245
  if (store.chatData?.thinkingResponse?.thinkingStream) {
7115
7246
  thinkingContentRef.current = store.chatData.thinkingResponse.thinkingStream;
@@ -7176,15 +7307,21 @@ const StreamedContent = ({ botData }) => {
7176
7307
  dispatch(smartBotActions.setCurrentAgentChatId(messageToStoreRef.current.uniqueChatId));
7177
7308
  }
7178
7309
  // Persist IDs for step form restream (ButtonContent reads these)
7179
- sessionStorage.setItem("stepForm_sessionId", messageToStoreRef.current.sessionId || "");
7180
- sessionStorage.setItem("stepForm_chatId", messageToStoreRef.current.uniqueChatId || "");
7181
- sessionStorage.setItem("stepForm_agentId", botData.inputBody?.agent_id || "");
7182
- sessionStorage.setItem("stepForm_baseUrl", baseUrl || "");
7183
- // Also sync module-level control object
7184
- stepFormStreamControl.sessionId = messageToStoreRef.current.sessionId || "";
7185
- stepFormStreamControl.chatId = messageToStoreRef.current.uniqueChatId || "";
7186
- stepFormStreamControl.agentId = botData.inputBody?.agent_id || "";
7187
- stepFormStreamControl.baseUrl = baseUrl || "";
7310
+ const _sid2 = messageToStoreRef.current.sessionId || "";
7311
+ const _cid2 = messageToStoreRef.current.uniqueChatId || "";
7312
+ const _aid2 = botData.inputBody?.agent_id || "";
7313
+ const _burl2 = baseUrl || "";
7314
+ sessionStorage.setItem("stepForm_sessionId", _sid2);
7315
+ sessionStorage.setItem("stepForm_chatId", _cid2);
7316
+ sessionStorage.setItem("stepForm_agentId", _aid2);
7317
+ sessionStorage.setItem("stepForm_baseUrl", _burl2);
7318
+ stepFormStreamControl.sessionId = _sid2;
7319
+ stepFormStreamControl.chatId = _cid2;
7320
+ stepFormStreamControl.agentId = _aid2;
7321
+ stepFormStreamControl.baseUrl = _burl2;
7322
+ // Persist completed/follow-up state so ButtonContent can read it after remount
7323
+ stepFormStreamControl.initValue = messageToStoreRef.current.initValue;
7324
+ stepFormStreamControl.uniqueChatId = _cid2;
7188
7325
  let appendedDataLength = 0;
7189
7326
  // Use appendedDataFromLastChunk for field number calculation like host app
7190
7327
  if (isArray(messageToStoreRef.current.appendedDataFromLastChunk)) {
@@ -7235,14 +7372,15 @@ const StreamedContent = ({ botData }) => {
7235
7372
  },
7236
7373
  },
7237
7374
  };
7375
+ const hasStepFormWidgets = !isEmpty(stepFormDataMapRef.current);
7238
7376
  processResponse(response, botData.inputBody, currentMode, botData.utilityObject.customChatConfig, {
7239
7377
  newChatData: chatDataInfoRef,
7240
7378
  isTabEnabled: true,
7241
7379
  steps: lodash.cloneDeep(stepRef.current),
7242
- currentTabValue: stepsDone ? "agent_response" : undefined,
7380
+ currentTabValue: (stepsDone && !hasStepFormWidgets) ? "agent_response" : "steps",
7243
7381
  questions: lodash.cloneDeep(questionsRef.current),
7244
7382
  questionsStepsMap: lodash.cloneDeep(questionsStepsMapRef.current),
7245
- stepFormDataMap: lodash.cloneDeep(stepFormDataMapRef.current),
7383
+ stepFormDataMap: { ...stepFormDataMapRef.current },
7246
7384
  }, activeConversationId);
7247
7385
  // [
7248
7386
  // {
@@ -7325,10 +7463,10 @@ const StreamedContent = ({ botData }) => {
7325
7463
  newChatData: chatDataInfoRef,
7326
7464
  isTabEnabled: true,
7327
7465
  steps: lodash.cloneDeep(stepRef.current),
7328
- currentTabValue: stepsDone ? "agent_response" : undefined,
7466
+ currentTabValue: stepsDone ? "agent_response" : "steps",
7329
7467
  questions: lodash.cloneDeep(questionsRef.current),
7330
7468
  questionsStepsMap: lodash.cloneDeep(questionsStepsMapRef.current),
7331
- stepFormDataMap: lodash.cloneDeep(stepFormDataMapRef.current),
7469
+ stepFormDataMap: { ...stepFormDataMapRef.current },
7332
7470
  }, activeConversationId);
7333
7471
  }
7334
7472
  // Clean up module-level Map entry - stream is fully processed
@@ -7472,7 +7610,7 @@ const StreamedContent = ({ botData }) => {
7472
7610
  * @returns {JSX.Element} Rendered content with optional blinking cursor
7473
7611
  */
7474
7612
  const renderContent = () => {
7475
- return (jsxRuntime.jsx("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 }) }));
7613
+ return (jsxRuntime.jsx("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 }) }));
7476
7614
  };
7477
7615
  if (currentMode === "agent") {
7478
7616
  return renderContent();
@@ -7814,6 +7952,24 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
7814
7952
  setTabValue("steps");
7815
7953
  return;
7816
7954
  }
7955
+ // Handle real-time widget chunks dispatched immediately by ButtonContent
7956
+ if (payload.status === "widget_chunk") {
7957
+ const chunks = payload.chunks || [];
7958
+ const newWidgets = [];
7959
+ chunks.forEach((data) => {
7960
+ if (data.status === "widget") {
7961
+ const widgetItems = isArray$1(data.widget_data) ? data.widget_data : [data.widget_data];
7962
+ widgetItems.forEach((item) => {
7963
+ if (item)
7964
+ newWidgets.push(item);
7965
+ });
7966
+ }
7967
+ });
7968
+ if (newWidgets.length > 0) {
7969
+ setWidgetContent((prev) => [...prev, ...newWidgets]);
7970
+ }
7971
+ return;
7972
+ }
7817
7973
  // Process all collected chunks at once (done or error)
7818
7974
  const chunks = payload.chunks || [];
7819
7975
  let newSteps = lodash.cloneDeep(stepsRef.current);
@@ -7887,6 +8043,13 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
7887
8043
  const formWidgetData = isArray$1(data.widget_data) ? data.widget_data : [data.widget_data];
7888
8044
  const currentIntent = data.current_intent || formWidgetData?.[0]?.current_intent;
7889
8045
  if (currentIntent) {
8046
+ // Auto-create question/intent entry if no prior step chunk created it
8047
+ if (!newQuestionsStepsMap[currentIntent]) {
8048
+ newQuestionsStepsMap[currentIntent] = [];
8049
+ if (!newQuestions.includes(currentIntent)) {
8050
+ newQuestions.push(currentIntent);
8051
+ }
8052
+ }
7890
8053
  const submitButton = {
7891
8054
  type: "button",
7892
8055
  data: {
@@ -7907,13 +8070,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
7907
8070
  };
7908
8071
  }
7909
8072
  }
7910
- if (data.status === "widget") {
7911
- const widgetItems = isArray$1(data.widget_data) ? data.widget_data : [data.widget_data];
7912
- widgetItems.forEach((item) => {
7913
- if (item)
7914
- newWidgets.push(item);
7915
- });
7916
- }
8073
+ if (data.status === "widget") ;
7917
8074
  if (data.status === "content" && data.message) {
7918
8075
  newWidgets.push({ type: "text", response: data.message });
7919
8076
  }
@@ -10537,7 +10694,21 @@ const ChatbotInput = (props) => {
10537
10694
  if (newChatScreen) {
10538
10695
  clearFilterValuesCache();
10539
10696
  }
10697
+ // Auto-focus editor on mount
10698
+ setTimeout(() => {
10699
+ if (editorRef.current) {
10700
+ editorRef.current.focus();
10701
+ }
10702
+ }, 100);
10540
10703
  }, []);
10704
+ // Effect: Re-focus editor when filter set changes (e.g. chip cleared)
10705
+ React.useEffect(() => {
10706
+ setTimeout(() => {
10707
+ if (editorRef.current) {
10708
+ editorRef.current.focus();
10709
+ }
10710
+ }, 50);
10711
+ }, [selectedFilterSet]);
10541
10712
  // Effect: Cleanup tooltips on unmount
10542
10713
  React.useEffect(() => {
10543
10714
  return () => {
@@ -10747,7 +10918,8 @@ const ChatbotInput = (props) => {
10747
10918
  !target.closest("button") &&
10748
10919
  !target.closest(".chat-actions") &&
10749
10920
  !target.closest(".filter-set-trigger-wrapper") &&
10750
- !target.closest(".filter-set-chip-clear")) {
10921
+ !target.closest(".filter-set-chip-clear") &&
10922
+ !target.closest(".mention-select-wrapper")) {
10751
10923
  editorRef.current.focus();
10752
10924
  }
10753
10925
  }, children: jsxRuntime.jsxs("div", { className: `chat-input-wrapper ${isFixed ? "stacked" : ""} ${selectedFilterSet ? "has-filter-selected" : ""} ${(!isFixed || inputValue === "") && !newChatScreen && !selectedFilterSet ? "empty" : ""} ${!newChatScreen && !isFixed && !selectedFilterSet ? "single-line-textarea" : ""}`, style: { height }, children: [jsxRuntime.jsxs("div", { className: "chat-input-left-actions", children: [jsxRuntime.jsxs("div", { className: "filter-set-trigger-wrapper", ref: filterSetSelectRef, children: [jsxRuntime.jsx(impactUiV3.Tooltip, { title: hasMentionsInEditor || showMentionSelect ? "Cannot use filter set while @ mentions are active" : "Add filter set", children: jsxRuntime.jsx("button", { type: "button", className: `filter-set-plus-btn${hasMentionsInEditor || showMentionSelect ? " disabled" : ""}`, onClick: () => {
@@ -11536,10 +11708,13 @@ const useStyles = styles.makeStyles({
11536
11708
  buttonWrapper: {
11537
11709
  marginTop: "16px",
11538
11710
  },
11711
+ hidden: {
11712
+ display: "none",
11713
+ },
11539
11714
  });
11540
11715
  const ChatbotSaveFilterComponent = (props) => {
11541
11716
  const classes = useStyles();
11542
- const { savedFilterSets } = props;
11717
+ const { savedFilterSets, partialClose } = props;
11543
11718
  const [showFilter, setShowFilter] = React.useState(!lodash.isEmpty(savedFilterSets));
11544
11719
  /**
11545
11720
  * onFilterDashboardClick function is called when we click the apply filter
@@ -11573,6 +11748,12 @@ const ChatbotSaveFilterComponent = (props) => {
11573
11748
  setShowFilter(true);
11574
11749
  }
11575
11750
  }, [savedFilterSets]);
11751
+ React.useEffect(() => {
11752
+ const drawer = document.querySelector(".MuiModal-root.MuiDrawer-root");
11753
+ if (drawer) {
11754
+ drawer.style.display = partialClose ? "none" : "";
11755
+ }
11756
+ }, [partialClose]);
11576
11757
  React.useEffect(() => {
11577
11758
  if (!showFilter)
11578
11759
  return;
@@ -11645,7 +11826,7 @@ const ChatbotSaveFilterComponent = (props) => {
11645
11826
  observer.observe(document.body, { childList: true, subtree: true });
11646
11827
  return () => observer.disconnect();
11647
11828
  }, [showFilter]);
11648
- return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: !showFilter ?
11829
+ return (jsxRuntime.jsx("div", { className: partialClose ? classes.hidden : undefined, children: !showFilter ?
11649
11830
  jsxRuntime.jsxs("div", { className: classes.container, children: [jsxRuntime.jsx(NoFilterSetSavedIcon, { width: "189px", height: "126px", className: classes.icon }), jsxRuntime.jsx("p", { className: classes.title, children: "No filter set saved!" }), jsxRuntime.jsx("p", { className: classes.subtitle, children: "Create and save a filter set to use as your default scope or apply it anytime during a conversation" }), jsxRuntime.jsx("div", { className: classes.buttonWrapper, children: jsxRuntime.jsx(impactUiV3.Button, { variant: "primary", onClick: () => setShowFilter(true), children: "Create A Filter Set" }) })] }) :
11650
11831
  jsxRuntime.jsx("div", { children: jsxRuntime.jsx(CoreComponentScreen, { showPageHeader: false,
11651
11832
  // Filter dashboard props
@@ -12054,7 +12235,6 @@ const SmartBot = (props) => {
12054
12235
  newMessage.utilityObject = originalUtilityObject;
12055
12236
  }
12056
12237
  message.jsx = (jsxRuntime.jsx(BotMessage, { botData: newMessage, state: loadingState, handleLikeDislike: handleLikeDislike, props: properties }));
12057
- message.firstMessage = true;
12058
12238
  let actualProps = {
12059
12239
  botData: newMessage,
12060
12240
  state: loadingState,
@@ -12062,6 +12242,7 @@ const SmartBot = (props) => {
12062
12242
  props: properties,
12063
12243
  };
12064
12244
  message.actualProps = actualProps;
12245
+ message.firstMessage = true;
12065
12246
  // message.enableLikes = true;
12066
12247
  }
12067
12248
  });
@@ -12500,18 +12681,50 @@ const SmartBot = (props) => {
12500
12681
  // isActive: activeTab.current.activeTab === "agent",
12501
12682
  // initialClick: true,
12502
12683
  onClick: (params) => {
12684
+ // if (localStorage.getItem("isStreaming") === "true") {
12685
+ // displaySnackMessages(
12686
+ // "Please wait till the current request is completed",
12687
+ // "warning"
12688
+ // );
12689
+ // return;
12690
+ // } else {
12691
+ // const agentConversations = chatDataInfoRef?.current[params?.name?.toLowerCase()]?.conversations;
12692
+ // const firstConversationId = agentConversations ? Object.keys(agentConversations)[0] : undefined;
12503
12693
  if (params?.name?.toLowerCase() === "saved filters") {
12504
12694
  setNewChatScreen(false);
12505
12695
  setShowChatPlaceholder(false);
12506
12696
  setShowSavedFilters(true);
12697
+ // if (
12698
+ // !isEmpty(
12699
+ // agentConversations?.[firstConversationId]?.messages
12700
+ // )
12701
+ // ) {
12702
+ // setShowChatPlaceholder(false);
12703
+ // } else {
12704
+ // setShowChatPlaceholder(true);
12705
+ // }
12507
12706
  }
12707
+ // setCurrentMode(params?.name?.toLowerCase());
12708
+ // if (firstConversationId) {
12709
+ // setActiveConversationId(firstConversationId);
12710
+ // }
12711
+ // localStorage.setItem(
12712
+ // "currentModeData",
12713
+ // params?.name?.toLowerCase()
12714
+ // );
12715
+ // setNewChatScreen(false);
12716
+ // activeTab.current.activeTab = "agent";
12717
+ // setIsStop(false);
12718
+ // }
12719
+ // setConversation([]);
12720
+ // chatDataInfoRef.current[currentMode] = [];
12508
12721
  },
12509
12722
  icon: jsxRuntime.jsx(SvgSaveFilterTab, {}),
12510
12723
  },
12511
12724
  ], utilityList: utilityList, isAssistantThinking: false, isCustomScreen: showChatPlaceholder ? showChatPlaceholder : showSavedFilters, customScreenJsx: showChatPlaceholder ?
12512
12725
  jsxRuntime.jsx(ChatPlaceholder, { dateFormat: dateFormat, chatDataRef: chatDataRef, currentMode: currentMode, setShowChatPlaceholder: setShowChatPlaceholder, setLoader: setLoader, setCurrentAgentId: setCurrentAgentId, baseUrl: baseUrl, setBaseUrl: setBaseUrl, setCurrentSessionId: setCurrentSessionId, customChatConfig: customChatConfig, chatDataInfoRef: chatDataInfoRef, setChatDataState: setChatDataState, userInput: userInput, legacyAgentScreen: legacyAgentScreen, activeConversationId: activeConversationId, chatBodyRef: chatBodyRef, chatbotContext: chatbotContext, setInitValue: setInitValue, setSessionId: setSessionId, thinkingContent: thinkingContext?.thinkingContent, setThinkingContent: setThinkingContent, isThinking: isThinking, setIsThinking: setIsThinking, chatId: chatId, setChatId: setChatId, isStop: isStop, setIsStop: setIsStop, functionsRef: functionsRef, functionsState: functionsState, setFunctionsState: setFunctionsState, thinkingHeaderMessage: thinkingContext?.thinkingHeaderMessage, setThinkingHeaderMessage: setThinkingHeaderMessage, uniqueChatId: uniqueChatId, setUniqueChatId: setUniqueChatId, fieldNumber: fieldNumber, setFieldNumber: setFieldNumber, setAdditionalArgs: setAdditionalArgs, displayQuestions: displayQuestions, questions: questions, setActiveConversationId: setActiveConversationId })
12513
12726
  :
12514
- jsxRuntime.jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
12727
+ jsxRuntime.jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets, partialClose: partialClose }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
12515
12728
  freeTextHeading: "Try adding more details :",
12516
12729
  freeTextContent: "Alan works better when you provide more context and pointed questions",
12517
12730
  }, isStopIcon: isStop, onStopIconClick: onStopIconClick, footerText: "AI-generated responses may contain errors\u2014please verify important information", showSuggestionBanner: showSavedFilters ? false : showSuggestionBanner, onCloseSuggestionBanner: () => {