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.
package/dist/index.esm.js CHANGED
@@ -5073,6 +5073,17 @@ const sseevent = (message, messageToStoreRef) => {
5073
5073
  messageToStoreRef.current.chatData.response =
5074
5074
  messageToStoreRef.current.chatData.response +
5075
5075
  "There is an error, please reach out to IA with this use case.";
5076
+ // Still process completed/follow-up status even on error chunks
5077
+ // so that initValue is set correctly and dummyButton is suppressed
5078
+ if (parsedData?.status === "completed" ||
5079
+ parsedData?.status === "follow-up") {
5080
+ messageToStoreRef.current.initValue = true;
5081
+ messageToStoreRef.current.sessionId = "";
5082
+ messageToStoreRef.current.uniqueChatId = parsedData?.chat_id
5083
+ ? parsedData.chat_id
5084
+ : "";
5085
+ messageToStoreRef.current.status = parsedData?.status;
5086
+ }
5076
5087
  return new MessageEvent(type, { data: data });
5077
5088
  }
5078
5089
  if (parsedData?.status === "thinking") {
@@ -5273,6 +5284,9 @@ const stepFormStreamControl = {
5273
5284
  chatId: "",
5274
5285
  agentId: "",
5275
5286
  baseUrl: "",
5287
+ // Completed/follow-up state — persists across ButtonContent remounts
5288
+ initValue: false,
5289
+ uniqueChatId: "",
5276
5290
  };
5277
5291
  const useStyles$5 = makeStyles((theme) => ({
5278
5292
  buttonContainer: {
@@ -5335,8 +5349,15 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
5335
5349
  };
5336
5350
  const callInitApiStream = (userInput) => {
5337
5351
  // Prefer module-level values (set synchronously by StreamedContent), fall back to sessionStorage
5338
- const sessionId = stepFormStreamControl.sessionId || sessionStorage.getItem("stepForm_sessionId") || "";
5339
- const chatId = stepFormStreamControl.chatId || sessionStorage.getItem("stepForm_chatId") || "";
5352
+ // If a previous completed/follow-up response updated the state, use those values.
5353
+ // Read from module-level stepFormStreamControl (survives remounts) instead of local messageStoreRef.
5354
+ const hasCompletedState = stepFormStreamControl.initValue === true;
5355
+ const sessionId = hasCompletedState
5356
+ ? (stepFormStreamControl.sessionId ?? "")
5357
+ : (stepFormStreamControl.sessionId || sessionStorage.getItem("stepForm_sessionId") || "");
5358
+ const chatId = hasCompletedState
5359
+ ? (stepFormStreamControl.uniqueChatId ?? "")
5360
+ : (stepFormStreamControl.chatId || sessionStorage.getItem("stepForm_chatId") || "");
5340
5361
  const agentId = stepFormStreamControl.agentId || sessionStorage.getItem("stepForm_agentId") || "";
5341
5362
  const baseUrl = stepFormStreamControl.baseUrl || sessionStorage.getItem("stepForm_baseUrl") || "";
5342
5363
  const payload = {
@@ -5344,9 +5365,14 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
5344
5365
  session_id: sessionId,
5345
5366
  chat_id: chatId,
5346
5367
  user_input: userInput,
5347
- init: false,
5368
+ init: hasCompletedState ? true : false,
5348
5369
  delay: 0.3,
5349
5370
  };
5371
+ // Reset the flag so subsequent calls don't re-use stale completed state
5372
+ if (hasCompletedState) {
5373
+ messageStoreRef.current.initValue = false;
5374
+ stepFormStreamControl.initValue = false;
5375
+ }
5350
5376
  const endPoint = baseUrl
5351
5377
  ? `${BASE_API}${baseUrl}/chatbot/agent/init`
5352
5378
  : `${BASE_API}/core/chatbot/agent/init`;
@@ -5388,6 +5414,10 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
5388
5414
  console.log("[ButtonContent] SSE chunk:", data);
5389
5415
  if (data?.status === "step" || data?.status === "step_form" || data?.status === "questions" || data?.status === "thinking" || data?.status === "widget") {
5390
5416
  chunksRef.push(data);
5417
+ // Dispatch widget chunks immediately for real-time rendering
5418
+ if (data?.status === "widget") {
5419
+ dispatch(setStepFormStreamData({ status: "widget_chunk", chunks: [data] }));
5420
+ }
5391
5421
  // If this chunk also carries [DONE], dispatch collected chunks now
5392
5422
  if (data?.message === "[DONE]") {
5393
5423
  stepFormStreamControl.isStreaming = false;
@@ -5396,13 +5426,25 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
5396
5426
  dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef] }));
5397
5427
  }
5398
5428
  }
5399
- else if (data?.status === "completed" || data?.message === "[DONE]") {
5429
+ else if (data?.status === "completed" || data?.status === "follow-up" || data?.message === "[DONE]") {
5430
+ // Update messageStoreRef the same way AxiosEventSource does for completed/follow-up
5431
+ if (data?.status === "completed" || data?.status === "follow-up") {
5432
+ messageStoreRef.current.initValue = true;
5433
+ messageStoreRef.current.sessionId = "";
5434
+ messageStoreRef.current.uniqueChatId = data?.chat_id ? data.chat_id : "";
5435
+ // Also persist on module-level object so it survives ButtonContent remounts
5436
+ stepFormStreamControl.initValue = true;
5437
+ stepFormStreamControl.sessionId = "";
5438
+ stepFormStreamControl.uniqueChatId = data?.chat_id ? data.chat_id : "";
5439
+ }
5400
5440
  // Stream ended — dispatch all collected chunks at once
5401
5441
  stepFormStreamControl.isStreaming = false;
5402
5442
  stepFormStreamControl.abort = null;
5403
5443
  window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
5404
- // Signal tab switch to agent_response when status is "completed"
5405
- if (data?.status === "completed") {
5444
+ // Signal tab switch to agent_response when status is "completed",
5445
+ // but only if the response doesn't contain a new step_form that needs user interaction
5446
+ const hasStepForm = chunksRef.some((c) => c.status === "step_form");
5447
+ if (data?.status === "completed" && !hasStepForm) {
5406
5448
  window.dispatchEvent(new CustomEvent("stepFormStreamCompleted"));
5407
5449
  }
5408
5450
  dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef] }));
@@ -5768,6 +5810,15 @@ const SliderContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
5768
5810
  return (jsx("div", { style: { width: "100%", marginTop: "10px" }, children: jsx(Slider, { header: header, headerOrientation: headerOrentiation, inputPosition: inputPosition, label: label, max: max, min: min, required: required, disabled: disabled || isFormDisabled, onChange: (e) => handleChange(e), value: sliderValue }) }));
5769
5811
  };
5770
5812
 
5813
+ const INITIAL_DISPLAY_COUNT = 100;
5814
+ const LOAD_MORE_COUNT = 100;
5815
+ const formatOption = (option) => ({
5816
+ ...option,
5817
+ label: replaceSpecialCharacter(option.label.toString()),
5818
+ });
5819
+ const formatSlice = (options, start, end) => {
5820
+ return options.slice(start, end).map(formatOption);
5821
+ };
5771
5822
  const SelectContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
5772
5823
  const formKey = `${messageIndex}_${bodyText?.paramName}`;
5773
5824
  const { header, inputPosition, labelOrientation, label, options, isRequired, isDisabled, isMulti, paramName } = bodyText;
@@ -5777,6 +5828,7 @@ const SelectContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
5777
5828
  const [currentSelectedOptions, setCurrentSelectedOptions] = useState(persistedFormValues?.[formKey] || []);
5778
5829
  const [isAllSelected, setIsAllSelected] = useState(false);
5779
5830
  const [initialOptions, setInitialOptions] = useState([]);
5831
+ const allOptionsRef = useRef([]);
5780
5832
  const chatbotContext = useSelector((state) => state.smartBotReducer.chatbotContext);
5781
5833
  const heirarchyKeyValuePairs = useSelector((state) => state.smartBotReducer.heirarchyKeyValuePairs);
5782
5834
  const dispatch = useDispatch();
@@ -5815,19 +5867,46 @@ const SelectContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
5815
5867
  }
5816
5868
  }, [persistedFormValues, formKey]);
5817
5869
  useEffect(() => {
5818
- let formattedOptions = options.map((option) => {
5819
- return {
5820
- ...option,
5821
- label: replaceSpecialCharacter(option.label.toString()),
5822
- };
5823
- });
5824
- setInitialOptions(formattedOptions);
5825
- setCurrentOptions(formattedOptions);
5870
+ allOptionsRef.current = options;
5871
+ const initialSlice = formatSlice(options, 0, INITIAL_DISPLAY_COUNT);
5872
+ setInitialOptions(initialSlice);
5873
+ setCurrentOptions(initialSlice);
5826
5874
  }, []);
5827
5875
  return (jsx("div", { style: { width: "100%", marginTop: "10px" }, children: jsx(Select, { currentOptions: currentOptions, setCurrentOptions: setCurrentOptions, label: heirarchyKeyValuePairs[paramName] || label, labelOrientation: labelOrientation,
5828
5876
  // inputPosition={inputPosition}
5829
5877
  // header={header}
5830
- 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 }) }));
5878
+ 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: () => {
5879
+ const allRaw = allOptionsRef.current;
5880
+ if (allRaw.length > 0 && currentOptions.length < allRaw.length) {
5881
+ const nextCount = Math.min(currentOptions.length + LOAD_MORE_COUNT, allRaw.length);
5882
+ const newBatch = formatSlice(allRaw, currentOptions.length, nextCount);
5883
+ const nextOptions = [...currentOptions, ...newBatch];
5884
+ setCurrentOptions(nextOptions);
5885
+ setInitialOptions(nextOptions);
5886
+ if (isAllSelected) {
5887
+ setCurrentSelectedOptions(nextOptions);
5888
+ }
5889
+ }
5890
+ }, onSelectAll: (e) => {
5891
+ if (e && e.target.checked) {
5892
+ setCurrentSelectedOptions([...currentOptions]);
5893
+ setIsAllSelected(true);
5894
+ const allValues = allOptionsRef.current.map((opt) => opt.value);
5895
+ chatbotContext[bodyText?.paramName] = {
5896
+ ...chatbotContext?.[bodyText?.paramName],
5897
+ [bodyText?.paramName]: allValues,
5898
+ updated: true,
5899
+ };
5900
+ dispatch(setChatbotContext(chatbotContext));
5901
+ dispatch(setPersistedFormValues({ [formKey]: currentOptions }));
5902
+ }
5903
+ else {
5904
+ setCurrentSelectedOptions([]);
5905
+ setIsAllSelected(false);
5906
+ }
5907
+ }, customPlaceholderAfterSelect: isAllSelected && allOptionsRef.current.length > 0
5908
+ ? allOptionsRef.current.length
5909
+ : null }) }));
5831
5910
  };
5832
5911
 
5833
5912
  const DatePickerContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
@@ -6475,10 +6554,8 @@ const getQuestionStatus$1 = (questionSteps) => {
6475
6554
  /**
6476
6555
  * Renders a single progress bar item (main point + sub-items)
6477
6556
  */
6478
- const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData, showSavedFilters = true, isFormDisabled, isRestreaming = false, onAllSubItemsAnimated = undefined }) => {
6479
- const baseStatus = getQuestionStatus$1(questionSteps);
6480
- // When restreaming and this is the last item, show as in-progress
6481
- const status = (isRestreaming && isLast) ? "in-progress" : baseStatus;
6557
+ const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData, showSavedFilters = true, isFormDisabled, onAllSubItemsAnimated = undefined }) => {
6558
+ const status = getQuestionStatus$1(questionSteps);
6482
6559
  const animatedCountRef = useRef(0);
6483
6560
  const [isExpanded, setIsExpanded] = useState(true);
6484
6561
  const dotClass = status === "completed"
@@ -6522,8 +6599,14 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
6522
6599
  const lastQuestionCompleted = lastQuestionSteps &&
6523
6600
  lastQuestionSteps.length > 0 &&
6524
6601
  lastQuestionSteps.every((s) => s.step_status === "completed");
6602
+ const hasStepFormData = Object.keys(stepFormDataMap).length > 0;
6525
6603
  useEffect(() => {
6526
6604
  if (done) {
6605
+ // Don't auto-switch to agent_response tab when there's a step form pending user interaction
6606
+ if (hasStepFormData) {
6607
+ setFinalStepDone(true);
6608
+ return;
6609
+ }
6527
6610
  if (!finalStepDone) {
6528
6611
  if (currentMode === "navigation") {
6529
6612
  let updatedSteps = steps.map((step) => ({
@@ -6573,7 +6656,7 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
6573
6656
  step_status: "not-completed",
6574
6657
  },
6575
6658
  ];
6576
- return (jsx("div", { className: classes.progressBarContainer, children: jsx(ProgressBarItem$1, { question: fallbackQuestion, questionSteps: fallbackSteps, isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled, showSavedFilters: true }) }));
6659
+ return (jsx("div", { className: classes.progressBarContainer, children: jsx(ProgressBarItem$1, { question: fallbackQuestion, questionSteps: fallbackSteps, isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled }) }));
6577
6660
  }
6578
6661
  return (jsxs("div", { className: classes.progressBarContainer, children: [questions.map((question, index) => {
6579
6662
  const questionData = questionsStepsMap[question];
@@ -6596,17 +6679,40 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
6596
6679
  }, children: jsx(ProgressBarItem$1, { question: "Thinking", questionSteps: [{ header: "", sub_header: "", step_status: "not-completed" }], isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled }) }))] }));
6597
6680
  };
6598
6681
 
6682
+ const renderWidgetItem = (item, index) => {
6683
+ try {
6684
+ const parsedData = parseResponse(item, item.type, "", "", true);
6685
+ if (!parsedData)
6686
+ return null;
6687
+ const key = `streaming-widget-${index}`;
6688
+ switch (parsedData.bodyType) {
6689
+ case "text":
6690
+ return jsx(TextContent, { bodyText: parsedData.bodyText, botData: parsedData }, key);
6691
+ case "table":
6692
+ return jsx(TableContent, { bodyText: parsedData.bodyText }, key);
6693
+ case "graph":
6694
+ return jsx(GraphContent, { bodyText: parsedData.bodyText }, key);
6695
+ default:
6696
+ return null;
6697
+ }
6698
+ }
6699
+ catch (e) {
6700
+ console.error("[AgentResponse] renderWidgetItem error:", e);
6701
+ return null;
6702
+ }
6703
+ };
6599
6704
  const AgentResponse$1 = (props) => {
6600
- const { content, isStreaming } = props;
6705
+ const { content, isStreaming, streamingWidgetData = [] } = props;
6601
6706
  const classes = useStyles$4();
6602
6707
  const chatClasses = useStyles$7();
6603
- return (jsx("div", { className: chatClasses.agentResponseContainer, children: content ? (jsxs(Typography, { className: chatClasses.bodyTextStyling, children: [jsx(TextRenderer, { text: content }), isStreaming && jsx("span", { className: classes.cursor })] })) : (
6604
- // Show cursor even when no content yet
6605
- isStreaming && jsx("span", { className: classes.cursor })) }));
6708
+ const renderedWidgets = streamingWidgetData
6709
+ .map((item, index) => renderWidgetItem(item, index))
6710
+ .filter(Boolean);
6711
+ 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 }))] }));
6606
6712
  };
6607
6713
 
6608
6714
  const StepsResponseTab = (props) => {
6609
- const { steps, setSteps, stepsDone, setStepsDone, finalStepDone, setFinalStepDone, content, isStreaming, stepChange, currentMode, questions, questionsStepsMap, stepFormDataMap, isFormDisabled, } = props;
6715
+ const { steps, setSteps, stepsDone, setStepsDone, finalStepDone, setFinalStepDone, content, isStreaming, stepChange, currentMode, questions, questionsStepsMap, stepFormDataMap, isFormDisabled, streamingWidgetData, } = props;
6610
6716
  const [tabValue, setTabValue] = useState("steps");
6611
6717
  const handleChangeTabValue = (_event, newValue) => {
6612
6718
  setTabValue(newValue);
@@ -6624,7 +6730,7 @@ const StepsResponseTab = (props) => {
6624
6730
  },
6625
6731
  ], tabPanels: [
6626
6732
  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 }),
6627
- jsx(AgentResponse$1, { content: content, isStreaming: isStreaming }),
6733
+ jsx(AgentResponse$1, { content: content, isStreaming: isStreaming, streamingWidgetData: streamingWidgetData }),
6628
6734
  ], value: tabValue }) }));
6629
6735
  };
6630
6736
 
@@ -6674,6 +6780,7 @@ const StreamedContent = ({ botData }) => {
6674
6780
  // const [thinkingContent, setThinkingContent] = useState("");
6675
6781
  const [thinkDone, setThinkDone] = useState(false);
6676
6782
  const [isStreaming, setIsStreaming] = useState(true);
6783
+ const [streamingWidgetData, setStreamingWidgetData] = useState([]);
6677
6784
  const [thinkingStarted, setThinkingStarted] = useState(false);
6678
6785
  const [isStreamingDone, setIsStreamingDone] = useState(false);
6679
6786
  const [isThinking, setIsThinking] = useState(false);
@@ -6848,7 +6955,7 @@ const StreamedContent = ({ botData }) => {
6848
6955
  }));
6849
6956
  return;
6850
6957
  }
6851
- if (data?.message || data?.status === "step" || data?.status === "step_form" || data?.status === "thinking" || data?.status === "questions") {
6958
+ if (data?.message || data?.status === "step" || data?.status === "step_form" || data?.status === "thinking" || data?.status === "questions" || data?.status === "widget") {
6852
6959
  if (data.status === "questions") {
6853
6960
  const incomingQuestions = data.widget_data?.[0]?.questions || [];
6854
6961
  questionsRef.current = incomingQuestions;
@@ -6961,6 +7068,15 @@ const StreamedContent = ({ botData }) => {
6961
7068
  : [data.widget_data];
6962
7069
  const currentIntent = data.current_intent || formWidgetData?.[0]?.current_intent;
6963
7070
  if (currentIntent) {
7071
+ // Auto-create question/intent entry if no prior step chunk created it
7072
+ if (!questionsStepsMapRef.current[currentIntent]) {
7073
+ questionsStepsMapRef.current[currentIntent] = [];
7074
+ if (!questionsRef.current.includes(currentIntent)) {
7075
+ questionsRef.current = [...questionsRef.current, currentIntent];
7076
+ setQuestions([...questionsRef.current]);
7077
+ }
7078
+ setQuestionsStepsMap(cloneDeep(questionsStepsMapRef.current));
7079
+ }
6964
7080
  const sendButton = document.getElementById("chat-input-send-button");
6965
7081
  const stepFormSubmitButton = {
6966
7082
  type: "button",
@@ -6981,7 +7097,7 @@ const StreamedContent = ({ botData }) => {
6981
7097
  widgets: [...formWidgetData, stepFormSubmitButton],
6982
7098
  showSavedFilters: data.show_saved_filters !== false,
6983
7099
  };
6984
- setStepFormDataMap(cloneDeep(stepFormDataMapRef.current));
7100
+ setStepFormDataMap({ ...stepFormDataMapRef.current });
6985
7101
  }
6986
7102
  setStepChange((prev) => !prev);
6987
7103
  // Persist IDs immediately when step_form arrives (AxiosEventSource already set them)
@@ -7000,12 +7116,20 @@ const StreamedContent = ({ botData }) => {
7000
7116
  stepFormStreamControl.baseUrl = _burl;
7001
7117
  // If this is the [DONE] chunk, mark streaming as complete
7002
7118
  if (data.message === "[DONE]") {
7119
+ setStepsDone(true);
7003
7120
  setIsStreamingDone(true);
7004
7121
  const doneState = streamStateMap.get(streamKey);
7005
7122
  if (doneState)
7006
7123
  doneState.completed = true;
7007
7124
  }
7008
7125
  }
7126
+ else if (data.status === "widget") {
7127
+ // Render widget data immediately as it arrives during streaming
7128
+ const widgetItems = isArray(data.widget_data)
7129
+ ? data.widget_data
7130
+ : [data.widget_data];
7131
+ setStreamingWidgetData((prev) => [...prev, ...widgetItems]);
7132
+ }
7009
7133
  else if (data.message !== "[DONE]") {
7010
7134
  if (!thinkingDoneRef?.current && currentMode === "agent") {
7011
7135
  thinkingDoneRef.current = true;
@@ -7088,6 +7212,13 @@ const StreamedContent = ({ botData }) => {
7088
7212
  const store = messageToStoreRef.current;
7089
7213
  // Restore accumulated content
7090
7214
  setContent(store.chatData?.response || "");
7215
+ // Restore widget data received so far
7216
+ if (isArray(store.appendedData) && store.appendedData.length > 0) {
7217
+ setStreamingWidgetData(store.appendedData);
7218
+ }
7219
+ else if (store.appendedData && !isArray(store.appendedData) && Object.keys(store.appendedData).length > 0) {
7220
+ setStreamingWidgetData([store.appendedData]);
7221
+ }
7091
7222
  // Restore thinking state
7092
7223
  if (store.chatData?.thinkingResponse?.thinkingStream) {
7093
7224
  thinkingContentRef.current = store.chatData.thinkingResponse.thinkingStream;
@@ -7154,15 +7285,21 @@ const StreamedContent = ({ botData }) => {
7154
7285
  dispatch(setCurrentAgentChatId(messageToStoreRef.current.uniqueChatId));
7155
7286
  }
7156
7287
  // Persist IDs for step form restream (ButtonContent reads these)
7157
- sessionStorage.setItem("stepForm_sessionId", messageToStoreRef.current.sessionId || "");
7158
- sessionStorage.setItem("stepForm_chatId", messageToStoreRef.current.uniqueChatId || "");
7159
- sessionStorage.setItem("stepForm_agentId", botData.inputBody?.agent_id || "");
7160
- sessionStorage.setItem("stepForm_baseUrl", baseUrl || "");
7161
- // Also sync module-level control object
7162
- stepFormStreamControl.sessionId = messageToStoreRef.current.sessionId || "";
7163
- stepFormStreamControl.chatId = messageToStoreRef.current.uniqueChatId || "";
7164
- stepFormStreamControl.agentId = botData.inputBody?.agent_id || "";
7165
- stepFormStreamControl.baseUrl = baseUrl || "";
7288
+ const _sid2 = messageToStoreRef.current.sessionId || "";
7289
+ const _cid2 = messageToStoreRef.current.uniqueChatId || "";
7290
+ const _aid2 = botData.inputBody?.agent_id || "";
7291
+ const _burl2 = baseUrl || "";
7292
+ sessionStorage.setItem("stepForm_sessionId", _sid2);
7293
+ sessionStorage.setItem("stepForm_chatId", _cid2);
7294
+ sessionStorage.setItem("stepForm_agentId", _aid2);
7295
+ sessionStorage.setItem("stepForm_baseUrl", _burl2);
7296
+ stepFormStreamControl.sessionId = _sid2;
7297
+ stepFormStreamControl.chatId = _cid2;
7298
+ stepFormStreamControl.agentId = _aid2;
7299
+ stepFormStreamControl.baseUrl = _burl2;
7300
+ // Persist completed/follow-up state so ButtonContent can read it after remount
7301
+ stepFormStreamControl.initValue = messageToStoreRef.current.initValue;
7302
+ stepFormStreamControl.uniqueChatId = _cid2;
7166
7303
  let appendedDataLength = 0;
7167
7304
  // Use appendedDataFromLastChunk for field number calculation like host app
7168
7305
  if (isArray(messageToStoreRef.current.appendedDataFromLastChunk)) {
@@ -7213,14 +7350,15 @@ const StreamedContent = ({ botData }) => {
7213
7350
  },
7214
7351
  },
7215
7352
  };
7353
+ const hasStepFormWidgets = !isEmpty(stepFormDataMapRef.current);
7216
7354
  processResponse(response, botData.inputBody, currentMode, botData.utilityObject.customChatConfig, {
7217
7355
  newChatData: chatDataInfoRef,
7218
7356
  isTabEnabled: true,
7219
7357
  steps: cloneDeep(stepRef.current),
7220
- currentTabValue: stepsDone ? "agent_response" : undefined,
7358
+ currentTabValue: (stepsDone && !hasStepFormWidgets) ? "agent_response" : "steps",
7221
7359
  questions: cloneDeep(questionsRef.current),
7222
7360
  questionsStepsMap: cloneDeep(questionsStepsMapRef.current),
7223
- stepFormDataMap: cloneDeep(stepFormDataMapRef.current),
7361
+ stepFormDataMap: { ...stepFormDataMapRef.current },
7224
7362
  }, activeConversationId);
7225
7363
  // [
7226
7364
  // {
@@ -7303,10 +7441,10 @@ const StreamedContent = ({ botData }) => {
7303
7441
  newChatData: chatDataInfoRef,
7304
7442
  isTabEnabled: true,
7305
7443
  steps: cloneDeep(stepRef.current),
7306
- currentTabValue: stepsDone ? "agent_response" : undefined,
7444
+ currentTabValue: stepsDone ? "agent_response" : "steps",
7307
7445
  questions: cloneDeep(questionsRef.current),
7308
7446
  questionsStepsMap: cloneDeep(questionsStepsMapRef.current),
7309
- stepFormDataMap: cloneDeep(stepFormDataMapRef.current),
7447
+ stepFormDataMap: { ...stepFormDataMapRef.current },
7310
7448
  }, activeConversationId);
7311
7449
  }
7312
7450
  // Clean up module-level Map entry - stream is fully processed
@@ -7450,7 +7588,7 @@ const StreamedContent = ({ botData }) => {
7450
7588
  * @returns {JSX.Element} Rendered content with optional blinking cursor
7451
7589
  */
7452
7590
  const renderContent = () => {
7453
- return (jsx("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 }) }));
7591
+ return (jsx("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 }) }));
7454
7592
  };
7455
7593
  if (currentMode === "agent") {
7456
7594
  return renderContent();
@@ -7792,6 +7930,24 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
7792
7930
  setTabValue("steps");
7793
7931
  return;
7794
7932
  }
7933
+ // Handle real-time widget chunks dispatched immediately by ButtonContent
7934
+ if (payload.status === "widget_chunk") {
7935
+ const chunks = payload.chunks || [];
7936
+ const newWidgets = [];
7937
+ chunks.forEach((data) => {
7938
+ if (data.status === "widget") {
7939
+ const widgetItems = isArray$2(data.widget_data) ? data.widget_data : [data.widget_data];
7940
+ widgetItems.forEach((item) => {
7941
+ if (item)
7942
+ newWidgets.push(item);
7943
+ });
7944
+ }
7945
+ });
7946
+ if (newWidgets.length > 0) {
7947
+ setWidgetContent((prev) => [...prev, ...newWidgets]);
7948
+ }
7949
+ return;
7950
+ }
7795
7951
  // Process all collected chunks at once (done or error)
7796
7952
  const chunks = payload.chunks || [];
7797
7953
  let newSteps = cloneDeep(stepsRef.current);
@@ -7865,6 +8021,13 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
7865
8021
  const formWidgetData = isArray$2(data.widget_data) ? data.widget_data : [data.widget_data];
7866
8022
  const currentIntent = data.current_intent || formWidgetData?.[0]?.current_intent;
7867
8023
  if (currentIntent) {
8024
+ // Auto-create question/intent entry if no prior step chunk created it
8025
+ if (!newQuestionsStepsMap[currentIntent]) {
8026
+ newQuestionsStepsMap[currentIntent] = [];
8027
+ if (!newQuestions.includes(currentIntent)) {
8028
+ newQuestions.push(currentIntent);
8029
+ }
8030
+ }
7868
8031
  const submitButton = {
7869
8032
  type: "button",
7870
8033
  data: {
@@ -7885,13 +8048,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
7885
8048
  };
7886
8049
  }
7887
8050
  }
7888
- if (data.status === "widget") {
7889
- const widgetItems = isArray$2(data.widget_data) ? data.widget_data : [data.widget_data];
7890
- widgetItems.forEach((item) => {
7891
- if (item)
7892
- newWidgets.push(item);
7893
- });
7894
- }
8051
+ if (data.status === "widget") ;
7895
8052
  if (data.status === "content" && data.message) {
7896
8053
  newWidgets.push({ type: "text", response: data.message });
7897
8054
  }
@@ -10515,7 +10672,21 @@ const ChatbotInput = (props) => {
10515
10672
  if (newChatScreen) {
10516
10673
  clearFilterValuesCache();
10517
10674
  }
10675
+ // Auto-focus editor on mount
10676
+ setTimeout(() => {
10677
+ if (editorRef.current) {
10678
+ editorRef.current.focus();
10679
+ }
10680
+ }, 100);
10518
10681
  }, []);
10682
+ // Effect: Re-focus editor when filter set changes (e.g. chip cleared)
10683
+ useEffect(() => {
10684
+ setTimeout(() => {
10685
+ if (editorRef.current) {
10686
+ editorRef.current.focus();
10687
+ }
10688
+ }, 50);
10689
+ }, [selectedFilterSet]);
10519
10690
  // Effect: Cleanup tooltips on unmount
10520
10691
  useEffect(() => {
10521
10692
  return () => {
@@ -10725,7 +10896,8 @@ const ChatbotInput = (props) => {
10725
10896
  !target.closest("button") &&
10726
10897
  !target.closest(".chat-actions") &&
10727
10898
  !target.closest(".filter-set-trigger-wrapper") &&
10728
- !target.closest(".filter-set-chip-clear")) {
10899
+ !target.closest(".filter-set-chip-clear") &&
10900
+ !target.closest(".mention-select-wrapper")) {
10729
10901
  editorRef.current.focus();
10730
10902
  }
10731
10903
  }, children: 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: [jsxs("div", { className: "chat-input-left-actions", children: [jsxs("div", { className: "filter-set-trigger-wrapper", ref: filterSetSelectRef, children: [jsx(Tooltip, { title: hasMentionsInEditor || showMentionSelect ? "Cannot use filter set while @ mentions are active" : "Add filter set", children: jsx("button", { type: "button", className: `filter-set-plus-btn${hasMentionsInEditor || showMentionSelect ? " disabled" : ""}`, onClick: () => {
@@ -11514,10 +11686,13 @@ const useStyles = makeStyles({
11514
11686
  buttonWrapper: {
11515
11687
  marginTop: "16px",
11516
11688
  },
11689
+ hidden: {
11690
+ display: "none",
11691
+ },
11517
11692
  });
11518
11693
  const ChatbotSaveFilterComponent = (props) => {
11519
11694
  const classes = useStyles();
11520
- const { savedFilterSets } = props;
11695
+ const { savedFilterSets, partialClose } = props;
11521
11696
  const [showFilter, setShowFilter] = useState(!isEmpty$1(savedFilterSets));
11522
11697
  /**
11523
11698
  * onFilterDashboardClick function is called when we click the apply filter
@@ -11551,6 +11726,12 @@ const ChatbotSaveFilterComponent = (props) => {
11551
11726
  setShowFilter(true);
11552
11727
  }
11553
11728
  }, [savedFilterSets]);
11729
+ useEffect(() => {
11730
+ const drawer = document.querySelector(".MuiModal-root.MuiDrawer-root");
11731
+ if (drawer) {
11732
+ drawer.style.display = partialClose ? "none" : "";
11733
+ }
11734
+ }, [partialClose]);
11554
11735
  useEffect(() => {
11555
11736
  if (!showFilter)
11556
11737
  return;
@@ -11623,7 +11804,7 @@ const ChatbotSaveFilterComponent = (props) => {
11623
11804
  observer.observe(document.body, { childList: true, subtree: true });
11624
11805
  return () => observer.disconnect();
11625
11806
  }, [showFilter]);
11626
- return (jsx(Fragment, { children: !showFilter ?
11807
+ return (jsx("div", { className: partialClose ? classes.hidden : undefined, children: !showFilter ?
11627
11808
  jsxs("div", { className: classes.container, children: [jsx(NoFilterSetSavedIcon, { width: "189px", height: "126px", className: classes.icon }), jsx("p", { className: classes.title, children: "No filter set saved!" }), 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" }), jsx("div", { className: classes.buttonWrapper, children: jsx(Button, { variant: "primary", onClick: () => setShowFilter(true), children: "Create A Filter Set" }) })] }) :
11628
11809
  jsx("div", { children: jsx(CoreComponentScreen, { showPageHeader: false,
11629
11810
  // Filter dashboard props
@@ -12032,7 +12213,6 @@ const SmartBot = (props) => {
12032
12213
  newMessage.utilityObject = originalUtilityObject;
12033
12214
  }
12034
12215
  message.jsx = (jsx(BotMessage, { botData: newMessage, state: loadingState, handleLikeDislike: handleLikeDislike, props: properties }));
12035
- message.firstMessage = true;
12036
12216
  let actualProps = {
12037
12217
  botData: newMessage,
12038
12218
  state: loadingState,
@@ -12040,6 +12220,7 @@ const SmartBot = (props) => {
12040
12220
  props: properties,
12041
12221
  };
12042
12222
  message.actualProps = actualProps;
12223
+ message.firstMessage = true;
12043
12224
  // message.enableLikes = true;
12044
12225
  }
12045
12226
  });
@@ -12478,18 +12659,50 @@ const SmartBot = (props) => {
12478
12659
  // isActive: activeTab.current.activeTab === "agent",
12479
12660
  // initialClick: true,
12480
12661
  onClick: (params) => {
12662
+ // if (localStorage.getItem("isStreaming") === "true") {
12663
+ // displaySnackMessages(
12664
+ // "Please wait till the current request is completed",
12665
+ // "warning"
12666
+ // );
12667
+ // return;
12668
+ // } else {
12669
+ // const agentConversations = chatDataInfoRef?.current[params?.name?.toLowerCase()]?.conversations;
12670
+ // const firstConversationId = agentConversations ? Object.keys(agentConversations)[0] : undefined;
12481
12671
  if (params?.name?.toLowerCase() === "saved filters") {
12482
12672
  setNewChatScreen(false);
12483
12673
  setShowChatPlaceholder(false);
12484
12674
  setShowSavedFilters(true);
12675
+ // if (
12676
+ // !isEmpty(
12677
+ // agentConversations?.[firstConversationId]?.messages
12678
+ // )
12679
+ // ) {
12680
+ // setShowChatPlaceholder(false);
12681
+ // } else {
12682
+ // setShowChatPlaceholder(true);
12683
+ // }
12485
12684
  }
12685
+ // setCurrentMode(params?.name?.toLowerCase());
12686
+ // if (firstConversationId) {
12687
+ // setActiveConversationId(firstConversationId);
12688
+ // }
12689
+ // localStorage.setItem(
12690
+ // "currentModeData",
12691
+ // params?.name?.toLowerCase()
12692
+ // );
12693
+ // setNewChatScreen(false);
12694
+ // activeTab.current.activeTab = "agent";
12695
+ // setIsStop(false);
12696
+ // }
12697
+ // setConversation([]);
12698
+ // chatDataInfoRef.current[currentMode] = [];
12486
12699
  },
12487
12700
  icon: jsx(SvgSaveFilterTab, {}),
12488
12701
  },
12489
12702
  ], utilityList: utilityList, isAssistantThinking: false, isCustomScreen: showChatPlaceholder ? showChatPlaceholder : showSavedFilters, customScreenJsx: showChatPlaceholder ?
12490
12703
  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 })
12491
12704
  :
12492
- jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
12705
+ jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets, partialClose: partialClose }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
12493
12706
  freeTextHeading: "Try adding more details :",
12494
12707
  freeTextContent: "Alan works better when you provide more context and pointed questions",
12495
12708
  }, isStopIcon: isStop, onStopIconClick: onStopIconClick, footerText: "AI-generated responses may contain errors\u2014please verify important information", showSuggestionBanner: showSavedFilters ? false : showSuggestionBanner, onCloseSuggestionBanner: () => {