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
|
-
|
|
5339
|
-
|
|
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
|
|
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
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
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,
|
|
6479
|
-
const
|
|
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
|
|
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
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
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(
|
|
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
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
stepFormStreamControl.
|
|
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" :
|
|
7358
|
+
currentTabValue: (stepsDone && !hasStepFormWidgets) ? "agent_response" : "steps",
|
|
7221
7359
|
questions: cloneDeep(questionsRef.current),
|
|
7222
7360
|
questionsStepsMap: cloneDeep(questionsStepsMapRef.current),
|
|
7223
|
-
stepFormDataMap:
|
|
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" :
|
|
7444
|
+
currentTabValue: stepsDone ? "agent_response" : "steps",
|
|
7307
7445
|
questions: cloneDeep(questionsRef.current),
|
|
7308
7446
|
questionsStepsMap: cloneDeep(questionsStepsMapRef.current),
|
|
7309
|
-
stepFormDataMap:
|
|
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(
|
|
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: () => {
|