impact-chatbot 2.3.37 → 2.3.39
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/components/message-template/components/message-content/ButtonContent.d.ts +8 -0
- package/dist/components/message-template/components/message-content/StepFormContent.d.ts +2 -1
- package/dist/components/message-template/components/message-content/tabular-content/components/Steps.d.ts +2 -1
- package/dist/index.cjs.js +172 -50
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +172 -50
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -26,6 +26,7 @@ import { CircularProgress, Typography, Grid } from '@mui/material';
|
|
|
26
26
|
import { fetchBaseUrl, replaceSpecialCharacter as replaceSpecialCharacter$1, fetchLegacyAgentScreen } from 'core/Utils/functions/utils';
|
|
27
27
|
import { Button, Modal, Slider, Select, DatePicker, DateRangePicker, Checkbox, RadioButtonGroup, Input, Tabs, Loader, Tooltip, ChatBotComponent } from 'impact-ui-v3';
|
|
28
28
|
import isArray$2 from 'lodash/isArray';
|
|
29
|
+
import { stopAgentFlow } from 'core/commonComponents/smartBot/services/chatbot-services';
|
|
29
30
|
import AgGridComponent from 'core/Utils/agGrid';
|
|
30
31
|
import agGridColumnFormatter from 'core/Utils/agGrid/column-formatter';
|
|
31
32
|
import CoreChart from 'core/Utils/core-charts';
|
|
@@ -33,7 +34,6 @@ import makeStyles$1 from '@mui/styles/makeStyles';
|
|
|
33
34
|
import ChevronRightIcon$1 from '@mui/icons-material/ChevronRight';
|
|
34
35
|
import FormatListBulletedOutlinedIcon from '@mui/icons-material/FormatListBulletedOutlined';
|
|
35
36
|
import PsychologyOutlinedIcon from '@mui/icons-material/PsychologyOutlined';
|
|
36
|
-
import { stopAgentFlow } from 'core/commonComponents/smartBot/services/chatbot-services';
|
|
37
37
|
import SaveOutlinedIcon from '@mui/icons-material/SaveOutlined';
|
|
38
38
|
import RangePicker from 'core/commonComponents/dateRangePicker';
|
|
39
39
|
import NoFilterSetSavedIcon from 'core/coreAssets/chatbot/noFilterSetSaved.svg';
|
|
@@ -5263,6 +5263,17 @@ const AxiosSource = (url, opts, messageToStoreRef) => {
|
|
|
5263
5263
|
}
|
|
5264
5264
|
};
|
|
5265
5265
|
|
|
5266
|
+
// Module-level control object for step-form SSE stream.
|
|
5267
|
+
// StreamedContent imports this to show/hide the stop icon during the second init stream.
|
|
5268
|
+
const stepFormStreamControl = {
|
|
5269
|
+
isStreaming: false,
|
|
5270
|
+
abort: null,
|
|
5271
|
+
// Session info — set by StreamedContent when step_form arrives
|
|
5272
|
+
sessionId: "",
|
|
5273
|
+
chatId: "",
|
|
5274
|
+
agentId: "",
|
|
5275
|
+
baseUrl: "",
|
|
5276
|
+
};
|
|
5266
5277
|
const useStyles$5 = makeStyles((theme) => ({
|
|
5267
5278
|
buttonContainer: {
|
|
5268
5279
|
display: 'flex',
|
|
@@ -5323,11 +5334,11 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5323
5334
|
sendButton.click();
|
|
5324
5335
|
};
|
|
5325
5336
|
const callInitApiStream = (userInput) => {
|
|
5326
|
-
//
|
|
5327
|
-
const sessionId =
|
|
5328
|
-
const chatId =
|
|
5329
|
-
const agentId =
|
|
5330
|
-
const baseUrl =
|
|
5337
|
+
// 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") || "";
|
|
5340
|
+
const agentId = stepFormStreamControl.agentId || sessionStorage.getItem("stepForm_agentId") || "";
|
|
5341
|
+
const baseUrl = stepFormStreamControl.baseUrl || sessionStorage.getItem("stepForm_baseUrl") || "";
|
|
5331
5342
|
const payload = {
|
|
5332
5343
|
agent_id: agentId,
|
|
5333
5344
|
session_id: sessionId,
|
|
@@ -5341,8 +5352,25 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5341
5352
|
: `${BASE_API}/core/chatbot/agent/init`;
|
|
5342
5353
|
// Collect all chunks, dispatch once when stream ends
|
|
5343
5354
|
const chunksRef = [];
|
|
5344
|
-
//
|
|
5355
|
+
// Expose stream control BEFORE Redux dispatch so SmartBot index.jsx can show stop icon
|
|
5356
|
+
stepFormStreamControl.isStreaming = true;
|
|
5357
|
+
stepFormStreamControl.abort = () => {
|
|
5358
|
+
if (sourceRef.current) {
|
|
5359
|
+
sourceRef.current.close();
|
|
5360
|
+
sourceRef.current = null;
|
|
5361
|
+
}
|
|
5362
|
+
stepFormStreamControl.isStreaming = false;
|
|
5363
|
+
stepFormStreamControl.abort = null;
|
|
5364
|
+
// Stop the agent flow on the backend (same as StreamedContent.abortStreaming)
|
|
5365
|
+
if (sessionId) {
|
|
5366
|
+
stopAgentFlow({ session_id: sessionId }, baseUrl);
|
|
5367
|
+
}
|
|
5368
|
+
dispatch(setStepFormStreamData({ status: "error", chunks: [...chunksRef] }));
|
|
5369
|
+
};
|
|
5370
|
+
// Signal that streaming has started (after setting stepFormStreamControl so useEffect sees the flag)
|
|
5345
5371
|
dispatch(setStepFormStreamData({ status: "streaming_start", chunks: [] }));
|
|
5372
|
+
// Fire DOM event so SmartBot can show stop icon (Redux gets cleared by TabularContent before parent effects run)
|
|
5373
|
+
window.dispatchEvent(new CustomEvent("stepFormStreamStart"));
|
|
5346
5374
|
sourceRef.current = AxiosSource(endPoint, {
|
|
5347
5375
|
method: "POST",
|
|
5348
5376
|
headers: {
|
|
@@ -5362,11 +5390,21 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5362
5390
|
chunksRef.push(data);
|
|
5363
5391
|
// If this chunk also carries [DONE], dispatch collected chunks now
|
|
5364
5392
|
if (data?.message === "[DONE]") {
|
|
5393
|
+
stepFormStreamControl.isStreaming = false;
|
|
5394
|
+
stepFormStreamControl.abort = null;
|
|
5395
|
+
window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
|
|
5365
5396
|
dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef] }));
|
|
5366
5397
|
}
|
|
5367
5398
|
}
|
|
5368
5399
|
else if (data?.status === "completed" || data?.message === "[DONE]") {
|
|
5369
5400
|
// Stream ended — dispatch all collected chunks at once
|
|
5401
|
+
stepFormStreamControl.isStreaming = false;
|
|
5402
|
+
stepFormStreamControl.abort = null;
|
|
5403
|
+
window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
|
|
5404
|
+
// Signal tab switch to agent_response when status is "completed"
|
|
5405
|
+
if (data?.status === "completed") {
|
|
5406
|
+
window.dispatchEvent(new CustomEvent("stepFormStreamCompleted"));
|
|
5407
|
+
}
|
|
5370
5408
|
dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef] }));
|
|
5371
5409
|
}
|
|
5372
5410
|
else if (data?.message) {
|
|
@@ -5379,6 +5417,9 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5379
5417
|
});
|
|
5380
5418
|
sourceRef.current.addEventListener("error", () => {
|
|
5381
5419
|
// On error, still dispatch whatever we collected
|
|
5420
|
+
stepFormStreamControl.isStreaming = false;
|
|
5421
|
+
stepFormStreamControl.abort = null;
|
|
5422
|
+
window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
|
|
5382
5423
|
dispatch(setStepFormStreamData({ status: "error", chunks: chunksRef }));
|
|
5383
5424
|
});
|
|
5384
5425
|
};
|
|
@@ -5432,7 +5473,7 @@ const TableContent = ({ bodyText }) => {
|
|
|
5432
5473
|
}, [row_data]);
|
|
5433
5474
|
const serverSideManualCallBack = async (manualbody, pageIndex, params) => {
|
|
5434
5475
|
try {
|
|
5435
|
-
const baseUrl =
|
|
5476
|
+
const baseUrl = sessionStorage.getItem("stepForm_baseUrl") || "";
|
|
5436
5477
|
const response = await getTableRecords(baseUrl, table_name, pageIndex + 1, page_size);
|
|
5437
5478
|
return {
|
|
5438
5479
|
data: response?.data?.data || [],
|
|
@@ -5990,7 +6031,7 @@ const ImageContent = ({ bodyText }) => {
|
|
|
5990
6031
|
* @param {Array} props.formData - Array of raw widget_data items from step_form chunk
|
|
5991
6032
|
* @param {number} props.messageIndex - Index for form state persistence keys
|
|
5992
6033
|
*/
|
|
5993
|
-
const StepFormContent = ({ formData, messageIndex = 0, isFormDisabled = false }) => {
|
|
6034
|
+
const StepFormContent = ({ formData, messageIndex = 0, isFormDisabled = false, showSavedFilters = true }) => {
|
|
5994
6035
|
const dispatch = useDispatch();
|
|
5995
6036
|
const savedFilterSets = useSelector((state) => state.smartBotReducer.savedFilterSets);
|
|
5996
6037
|
const persistedFormValues = useSelector((state) => state.smartBotReducer.persistedFormValues);
|
|
@@ -6161,7 +6202,7 @@ const StepFormContent = ({ formData, messageIndex = 0, isFormDisabled = false })
|
|
|
6161
6202
|
});
|
|
6162
6203
|
if (formFields.length === 0 && buttonItems.length === 0)
|
|
6163
6204
|
return null;
|
|
6164
|
-
return (jsxs("div", { className: "step-form-content", children: [filterSetOptions.length > 0 && (jsx("div", { style: { width: "100%", marginTop: "10px" }, children: jsx(Select, { currentOptions: filterSetCurrentOptions, setCurrentOptions: setFilterSetCurrentOptions, label: "Saved Filter Sets", labelOrientation: "top", isRequired: false, isDisabled: savedFilterDisabled, handleChange: (selected) => onFilterSetChange(selected), isCloseWhenClickOutside: true, setIsOpen: setIsFilterSetOpen, isOpen: isFilterSetOpen, selectedOptions: selectedFilterSet, setSelectedOptions: setSelectedFilterSet, initialOptions: filterSetOptions, isMulti: false, isClearable: true }) })), filterSetOptions.length > 0 && (jsx("hr", { style: { border: "none", borderTop: "1px solid #E0E0E0", margin: "12px 0" } })), jsx("div", { style: {
|
|
6205
|
+
return (jsxs("div", { className: "step-form-content", children: [showSavedFilters && filterSetOptions.length > 0 && (jsx("div", { style: { width: "100%", marginTop: "10px" }, children: jsx(Select, { currentOptions: filterSetCurrentOptions, setCurrentOptions: setFilterSetCurrentOptions, label: "Saved Filter Sets", labelOrientation: "top", isRequired: false, isDisabled: savedFilterDisabled, handleChange: (selected) => onFilterSetChange(selected), isCloseWhenClickOutside: true, setIsOpen: setIsFilterSetOpen, isOpen: isFilterSetOpen, selectedOptions: selectedFilterSet, setSelectedOptions: setSelectedFilterSet, initialOptions: filterSetOptions, isMulti: false, isClearable: true }) })), showSavedFilters && filterSetOptions.length > 0 && (jsx("hr", { style: { border: "none", borderTop: "1px solid #E0E0E0", margin: "12px 0" } })), jsx("div", { style: {
|
|
6165
6206
|
...(isFilterSelected && !isFormDisabled ? { pointerEvents: "none", opacity: 0.5 } : {}),
|
|
6166
6207
|
}, children: formFields }), buttonItems] }));
|
|
6167
6208
|
};
|
|
@@ -6234,8 +6275,8 @@ const useStyles$3 = makeStyles$1((theme) => ({
|
|
|
6234
6275
|
"&.completed": {
|
|
6235
6276
|
width: pxToRem(10),
|
|
6236
6277
|
height: pxToRem(10),
|
|
6237
|
-
background:
|
|
6238
|
-
border: `${pxToRem(3)} solid
|
|
6278
|
+
background: "#4CAF50",
|
|
6279
|
+
border: `${pxToRem(3)} solid #C8E6C9`,
|
|
6239
6280
|
boxSizing: "content-box",
|
|
6240
6281
|
},
|
|
6241
6282
|
"&.in-progress": {
|
|
@@ -6383,9 +6424,11 @@ const getQuestionStatus$1 = (questionSteps) => {
|
|
|
6383
6424
|
/**
|
|
6384
6425
|
* Renders a single progress bar item (main point + sub-items)
|
|
6385
6426
|
*/
|
|
6386
|
-
const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData, isFormDisabled }) => {
|
|
6387
|
-
const
|
|
6388
|
-
|
|
6427
|
+
const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData, showSavedFilters = true, isFormDisabled, isRestreaming = false }) => {
|
|
6428
|
+
const baseStatus = getQuestionStatus$1(questionSteps);
|
|
6429
|
+
// When restreaming and this is the last item, show as in-progress
|
|
6430
|
+
const status = (isRestreaming && isLast) ? "in-progress" : baseStatus;
|
|
6431
|
+
const [isExpanded, setIsExpanded] = useState(true);
|
|
6389
6432
|
const dotClass = status === "completed"
|
|
6390
6433
|
? "completed"
|
|
6391
6434
|
: status === "in-progress"
|
|
@@ -6409,11 +6452,8 @@ const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData,
|
|
|
6409
6452
|
if (status === "in-progress" || status === "error" || formData) {
|
|
6410
6453
|
setIsExpanded(true);
|
|
6411
6454
|
}
|
|
6412
|
-
else if (status === "completed" && !formData) {
|
|
6413
|
-
setIsExpanded(false);
|
|
6414
|
-
}
|
|
6415
6455
|
}, [status, formData]);
|
|
6416
|
-
return (jsxs("div", { className: classes.progressItem, children: [jsxs("div", { className: classes.progressTrack, children: [jsx("div", { className: `${classes.progressDot} ${dotClass}` }), !isLast && jsx("div", { className: `${classes.progressLine} ${lineClass}` })] }), jsxs("div", { className: classes.progressContent, children: [jsxs("div", { className: classes.progressHeader, onClick: handleToggle, children: [jsx("span", { className: `${classes.progressHeaderText} ${textClass}`, children: question }), hasSubItems && (jsx(ChevronRightIcon$1, { className: `${classes.progressChevron} ${textClass} ${isExpanded ? "expanded" : ""}` }))] }), hasSubItems && isExpanded && status === "in-progress" && (jsxs("div", { className: classes.reasoningLabel, children: [jsx(SvgReasoningIcon, {}), "Reasoning..."] })), hasSubItems && isExpanded && (jsx("div", { className: classes.progressSubItems, style: { opacity: isExpanded ? 1 : 0 }, children: questionSteps.map((step, idx) => (jsxs("div", { className: classes.progressSubItem, children: [step.header, step.sub_header ? ` - ${step.sub_header}` : ""] }, idx))) })), formData && isExpanded && (jsx("div", { className: classes.stepFormContainer, children: jsx(StepFormContent, { formData: formData, isFormDisabled: isFormDisabled }) }))] })] }));
|
|
6456
|
+
return (jsxs("div", { className: classes.progressItem, children: [jsxs("div", { className: classes.progressTrack, children: [jsx("div", { className: `${classes.progressDot} ${dotClass}` }), !isLast && jsx("div", { className: `${classes.progressLine} ${lineClass}` })] }), jsxs("div", { className: classes.progressContent, children: [jsxs("div", { className: classes.progressHeader, onClick: handleToggle, children: [jsx("span", { className: `${classes.progressHeaderText} ${textClass}`, children: question }), hasSubItems && (jsx(ChevronRightIcon$1, { className: `${classes.progressChevron} ${textClass} ${isExpanded ? "expanded" : ""}` }))] }), hasSubItems && isExpanded && status === "in-progress" && (jsxs("div", { className: classes.reasoningLabel, children: [jsx(SvgReasoningIcon, {}), "Reasoning..."] })), hasSubItems && isExpanded && (jsx("div", { className: classes.progressSubItems, style: { maxHeight: isExpanded ? "500px" : "0", opacity: isExpanded ? 1 : 0 }, children: questionSteps.map((step, idx) => (jsxs("div", { className: classes.progressSubItem, children: [step.header, step.sub_header ? ` - ${step.sub_header}` : ""] }, idx))) })), formData && isExpanded && (jsx("div", { className: classes.stepFormContainer, children: jsx(StepFormContent, { formData: formData, isFormDisabled: isFormDisabled, showSavedFilters: showSavedFilters }) }))] })] }));
|
|
6417
6457
|
};
|
|
6418
6458
|
const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, setFinalStepDone, stepChange, currentMode, questions = [], questionsStepsMap = {}, stepFormDataMap = {}, isFormDisabled = false, }) => {
|
|
6419
6459
|
const classes = useStyles$3();
|
|
@@ -6463,7 +6503,7 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
|
|
|
6463
6503
|
step_status: "not-completed",
|
|
6464
6504
|
},
|
|
6465
6505
|
];
|
|
6466
|
-
return (jsx("div", { className: classes.progressBarContainer, children: jsx(ProgressBarItem$1, { question: fallbackQuestion, questionSteps: fallbackSteps, isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled }) }));
|
|
6506
|
+
return (jsx("div", { className: classes.progressBarContainer, children: jsx(ProgressBarItem$1, { question: fallbackQuestion, questionSteps: fallbackSteps, isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled, showSavedFilters: true }) }));
|
|
6467
6507
|
}
|
|
6468
6508
|
return (jsx("div", { className: classes.progressBarContainer, children: questions.map((question, index) => {
|
|
6469
6509
|
const questionData = questionsStepsMap[question];
|
|
@@ -6474,8 +6514,10 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
|
|
|
6474
6514
|
step_status: "not-completed",
|
|
6475
6515
|
},
|
|
6476
6516
|
];
|
|
6477
|
-
const
|
|
6478
|
-
|
|
6517
|
+
const formEntry = stepFormDataMap[question] || null;
|
|
6518
|
+
const formData = formEntry ? (Array.isArray(formEntry) ? formEntry : formEntry.widgets) : null;
|
|
6519
|
+
const showSavedFilters = formEntry && !Array.isArray(formEntry) ? formEntry.showSavedFilters : true;
|
|
6520
|
+
return (jsx(ProgressBarItem$1, { question: question, questionSteps: questionSteps, isLast: index === questions.length - 1, classes: classes, formData: formData, isFormDisabled: isFormDisabled, showSavedFilters: showSavedFilters }, index));
|
|
6479
6521
|
}) }));
|
|
6480
6522
|
};
|
|
6481
6523
|
|
|
@@ -6657,7 +6699,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
6657
6699
|
// }
|
|
6658
6700
|
let endPoint = botData?.utilityObject?.endpoint
|
|
6659
6701
|
? `${BASE_API}${botData?.utilityObject?.endpoint}`
|
|
6660
|
-
: `${BASE_API}/core/chatbot/navigation-
|
|
6702
|
+
: `${BASE_API}/core/chatbot/navigation-v2`;
|
|
6661
6703
|
let method = botData?.utilityObject?.method
|
|
6662
6704
|
? botData?.utilityObject?.method
|
|
6663
6705
|
: "PUT";
|
|
@@ -6729,6 +6771,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
6729
6771
|
session_id: data?.session_id || "",
|
|
6730
6772
|
},
|
|
6731
6773
|
}));
|
|
6774
|
+
return;
|
|
6732
6775
|
}
|
|
6733
6776
|
if (data?.message || data?.status === "step" || data?.status === "step_form" || data?.status === "thinking" || data?.status === "questions") {
|
|
6734
6777
|
if (data.status === "questions") {
|
|
@@ -6855,15 +6898,27 @@ const StreamedContent = ({ botData }) => {
|
|
|
6855
6898
|
],
|
|
6856
6899
|
},
|
|
6857
6900
|
};
|
|
6858
|
-
stepFormDataMapRef.current[currentIntent] =
|
|
6901
|
+
stepFormDataMapRef.current[currentIntent] = {
|
|
6902
|
+
widgets: [...formWidgetData, stepFormSubmitButton],
|
|
6903
|
+
showSavedFilters: data.show_saved_filters !== false,
|
|
6904
|
+
};
|
|
6859
6905
|
setStepFormDataMap(cloneDeep(stepFormDataMapRef.current));
|
|
6860
6906
|
}
|
|
6861
6907
|
setStepChange((prev) => !prev);
|
|
6862
6908
|
// Persist IDs immediately when step_form arrives (AxiosEventSource already set them)
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6909
|
+
const _sid = messageToStoreRef.current.sessionId || "";
|
|
6910
|
+
const _cid = messageToStoreRef.current.uniqueChatId || "";
|
|
6911
|
+
const _aid = botData.inputBody?.agent_id || "";
|
|
6912
|
+
const _burl = baseUrl || "";
|
|
6913
|
+
sessionStorage.setItem("stepForm_sessionId", _sid);
|
|
6914
|
+
sessionStorage.setItem("stepForm_chatId", _cid);
|
|
6915
|
+
sessionStorage.setItem("stepForm_agentId", _aid);
|
|
6916
|
+
sessionStorage.setItem("stepForm_baseUrl", _burl);
|
|
6917
|
+
// Also set on module-level control object (survives async timing issues)
|
|
6918
|
+
stepFormStreamControl.sessionId = _sid;
|
|
6919
|
+
stepFormStreamControl.chatId = _cid;
|
|
6920
|
+
stepFormStreamControl.agentId = _aid;
|
|
6921
|
+
stepFormStreamControl.baseUrl = _burl;
|
|
6867
6922
|
// If this is the [DONE] chunk, mark streaming as complete
|
|
6868
6923
|
if (data.message === "[DONE]") {
|
|
6869
6924
|
setIsStreamingDone(true);
|
|
@@ -6873,7 +6928,6 @@ const StreamedContent = ({ botData }) => {
|
|
|
6873
6928
|
}
|
|
6874
6929
|
}
|
|
6875
6930
|
else if (data.message !== "[DONE]") {
|
|
6876
|
-
setStepsDone(true);
|
|
6877
6931
|
if (!thinkingDoneRef?.current && currentMode === "agent") {
|
|
6878
6932
|
thinkingDoneRef.current = true;
|
|
6879
6933
|
setThinkDone(true);
|
|
@@ -6900,6 +6954,10 @@ const StreamedContent = ({ botData }) => {
|
|
|
6900
6954
|
});
|
|
6901
6955
|
}
|
|
6902
6956
|
else {
|
|
6957
|
+
// message === "[DONE]" with status "completed" — switch to agent_response tab
|
|
6958
|
+
if (data.status === "completed") {
|
|
6959
|
+
setStepsDone(true);
|
|
6960
|
+
}
|
|
6903
6961
|
setIsStreamingDone(true);
|
|
6904
6962
|
const doneState = streamStateMap.get(streamKey);
|
|
6905
6963
|
if (doneState)
|
|
@@ -7017,10 +7075,15 @@ const StreamedContent = ({ botData }) => {
|
|
|
7017
7075
|
dispatch(setCurrentAgentChatId(messageToStoreRef.current.uniqueChatId));
|
|
7018
7076
|
}
|
|
7019
7077
|
// Persist IDs for step form restream (ButtonContent reads these)
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7078
|
+
sessionStorage.setItem("stepForm_sessionId", messageToStoreRef.current.sessionId || "");
|
|
7079
|
+
sessionStorage.setItem("stepForm_chatId", messageToStoreRef.current.uniqueChatId || "");
|
|
7080
|
+
sessionStorage.setItem("stepForm_agentId", botData.inputBody?.agent_id || "");
|
|
7081
|
+
sessionStorage.setItem("stepForm_baseUrl", baseUrl || "");
|
|
7082
|
+
// Also sync module-level control object
|
|
7083
|
+
stepFormStreamControl.sessionId = messageToStoreRef.current.sessionId || "";
|
|
7084
|
+
stepFormStreamControl.chatId = messageToStoreRef.current.uniqueChatId || "";
|
|
7085
|
+
stepFormStreamControl.agentId = botData.inputBody?.agent_id || "";
|
|
7086
|
+
stepFormStreamControl.baseUrl = baseUrl || "";
|
|
7024
7087
|
let appendedDataLength = 0;
|
|
7025
7088
|
// Use appendedDataFromLastChunk for field number calculation like host app
|
|
7026
7089
|
if (isArray(messageToStoreRef.current.appendedDataFromLastChunk)) {
|
|
@@ -7075,7 +7138,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
7075
7138
|
newChatData: chatDataInfoRef,
|
|
7076
7139
|
isTabEnabled: true,
|
|
7077
7140
|
steps: cloneDeep(stepRef.current),
|
|
7078
|
-
currentTabValue: "agent_response",
|
|
7141
|
+
currentTabValue: stepsDone ? "agent_response" : undefined,
|
|
7079
7142
|
questions: cloneDeep(questionsRef.current),
|
|
7080
7143
|
questionsStepsMap: cloneDeep(questionsStepsMapRef.current),
|
|
7081
7144
|
stepFormDataMap: cloneDeep(stepFormDataMapRef.current),
|
|
@@ -7161,7 +7224,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
7161
7224
|
newChatData: chatDataInfoRef,
|
|
7162
7225
|
isTabEnabled: true,
|
|
7163
7226
|
steps: cloneDeep(stepRef.current),
|
|
7164
|
-
currentTabValue: "agent_response",
|
|
7227
|
+
currentTabValue: stepsDone ? "agent_response" : undefined,
|
|
7165
7228
|
questions: cloneDeep(questionsRef.current),
|
|
7166
7229
|
questionsStepsMap: cloneDeep(questionsStepsMapRef.current),
|
|
7167
7230
|
stepFormDataMap: cloneDeep(stepFormDataMapRef.current),
|
|
@@ -7373,8 +7436,8 @@ const useStyles$2 = makeStyles$1((theme) => ({
|
|
|
7373
7436
|
"&.completed": {
|
|
7374
7437
|
width: pxToRem(10),
|
|
7375
7438
|
height: pxToRem(10),
|
|
7376
|
-
background:
|
|
7377
|
-
border: `${pxToRem(3)} solid
|
|
7439
|
+
background: "#4CAF50",
|
|
7440
|
+
border: `${pxToRem(3)} solid #C8E6C9`,
|
|
7378
7441
|
boxSizing: "content-box",
|
|
7379
7442
|
},
|
|
7380
7443
|
"&.in-progress": {
|
|
@@ -7516,11 +7579,11 @@ const getQuestionStatus = (questionSteps) => {
|
|
|
7516
7579
|
/**
|
|
7517
7580
|
* Renders a single progress bar item (main point + sub-items)
|
|
7518
7581
|
*/
|
|
7519
|
-
const ProgressBarItem = ({ question, questionSteps, isLast, classes, formData, isFormDisabled, isRestreaming = false }) => {
|
|
7582
|
+
const ProgressBarItem = ({ question, questionSteps, isLast, classes, formData, isFormDisabled, isRestreaming = false, showSavedFilters = true }) => {
|
|
7520
7583
|
const baseStatus = getQuestionStatus(questionSteps);
|
|
7521
7584
|
// When restreaming and this is the last item, show as in-progress
|
|
7522
7585
|
const status = (isRestreaming && isLast) ? "in-progress" : baseStatus;
|
|
7523
|
-
const [isExpanded, setIsExpanded] = useState(
|
|
7586
|
+
const [isExpanded, setIsExpanded] = useState(true);
|
|
7524
7587
|
const dotClass = status === "completed"
|
|
7525
7588
|
? "completed"
|
|
7526
7589
|
: status === "in-progress"
|
|
@@ -7545,9 +7608,9 @@ const ProgressBarItem = ({ question, questionSteps, isLast, classes, formData, i
|
|
|
7545
7608
|
setIsExpanded(true);
|
|
7546
7609
|
}
|
|
7547
7610
|
}, [status, formData]);
|
|
7548
|
-
return (jsxs("div", { className: classes.progressItem, children: [jsxs("div", { className: classes.progressTrack, children: [jsx("div", { className: `${classes.progressDot} ${dotClass}` }), !isLast && jsx("div", { className: `${classes.progressLine} ${lineClass}` })] }), jsxs("div", { className: classes.progressContent, children: [jsxs("div", { className: classes.progressHeader, onClick: handleToggle, children: [jsx("span", { className: `${classes.progressHeaderText} ${textClass}`, children: question }), hasSubItems && (jsx(ChevronRightIcon$1, { className: `${classes.progressChevron} ${textClass} ${isExpanded ? "expanded" : ""}` }))] }), hasSubItems && isExpanded && status === "in-progress" && (jsxs("div", { className: classes.reasoningLabel, children: [jsx(SvgReasoningIcon, {}), "Reasoning..."] })), hasSubItems && isExpanded && (jsx("div", { className: classes.progressSubItems, style: { maxHeight: isExpanded ? "500px" : "0", opacity: isExpanded ? 1 : 0 }, children: questionSteps.map((step, idx) => (jsxs("div", { className: classes.progressSubItem, children: [step.header, step.sub_header ? ` - ${step.sub_header}` : ""] }, idx))) })), formData && isExpanded && (jsx("div", { className: classes.stepFormContainer, children: jsx(StepFormContent, { formData: formData, isFormDisabled: isFormDisabled }) }))] })] }));
|
|
7611
|
+
return (jsxs("div", { className: classes.progressItem, children: [jsxs("div", { className: classes.progressTrack, children: [jsx("div", { className: `${classes.progressDot} ${dotClass}` }), !isLast && jsx("div", { className: `${classes.progressLine} ${lineClass}` })] }), jsxs("div", { className: classes.progressContent, children: [jsxs("div", { className: classes.progressHeader, onClick: handleToggle, children: [jsx("span", { className: `${classes.progressHeaderText} ${textClass}`, children: question }), hasSubItems && (jsx(ChevronRightIcon$1, { className: `${classes.progressChevron} ${textClass} ${isExpanded ? "expanded" : ""}` }))] }), hasSubItems && isExpanded && status === "in-progress" && (jsxs("div", { className: classes.reasoningLabel, children: [jsx(SvgReasoningIcon, {}), "Reasoning..."] })), hasSubItems && isExpanded && (jsx("div", { className: classes.progressSubItems, style: { maxHeight: isExpanded ? "500px" : "0", opacity: isExpanded ? 1 : 0 }, children: questionSteps.map((step, idx) => (jsxs("div", { className: classes.progressSubItem, children: [step.header, step.sub_header ? ` - ${step.sub_header}` : ""] }, idx))) })), formData && isExpanded && (jsx("div", { className: classes.stepFormContainer, children: jsx(StepFormContent, { formData: formData, isFormDisabled: isFormDisabled, showSavedFilters: showSavedFilters }) }))] })] }));
|
|
7549
7612
|
};
|
|
7550
|
-
const Steps = ({ steps, questions = [], questionsStepsMap = {}, stepFormDataMap = {}, isFormDisabled = false, isRestreaming = false }) => {
|
|
7613
|
+
const Steps = ({ steps, questions = [], questionsStepsMap = {}, stepFormDataMap = {}, isFormDisabled = false, activeFormIntent = null, isRestreaming = false }) => {
|
|
7551
7614
|
const classes = useStyles$2();
|
|
7552
7615
|
useState(false);
|
|
7553
7616
|
const hasQuestions = questions.length > 0;
|
|
@@ -7567,8 +7630,15 @@ const Steps = ({ steps, questions = [], questionsStepsMap = {}, stepFormDataMap
|
|
|
7567
7630
|
step_status: "completed",
|
|
7568
7631
|
},
|
|
7569
7632
|
];
|
|
7570
|
-
const
|
|
7571
|
-
|
|
7633
|
+
const formEntry = stepFormDataMap[question] || null;
|
|
7634
|
+
// Support both old array format and new object format { widgets, showSavedFilters }
|
|
7635
|
+
const formData = formEntry ? (Array.isArray(formEntry) ? formEntry : formEntry.widgets) : null;
|
|
7636
|
+
const showSavedFilters = formEntry && !Array.isArray(formEntry) ? formEntry.showSavedFilters : true;
|
|
7637
|
+
// If activeFormIntent is set, only the matching form is enabled; all others stay disabled
|
|
7638
|
+
const formDisabledForThis = activeFormIntent
|
|
7639
|
+
? question !== activeFormIntent
|
|
7640
|
+
: isFormDisabled;
|
|
7641
|
+
return (jsx(ProgressBarItem, { question: question, questionSteps: questionSteps, isLast: index === questions.length - 1, classes: classes, formData: formData, isFormDisabled: formDisabledForThis, isRestreaming: isRestreaming, showSavedFilters: showSavedFilters }, index));
|
|
7572
7642
|
}) }));
|
|
7573
7643
|
};
|
|
7574
7644
|
|
|
@@ -7600,6 +7670,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7600
7670
|
const [isRestreaming, setIsRestreaming] = useState(false);
|
|
7601
7671
|
const [stepFormSubmitted, setStepFormSubmitted] = useState(false);
|
|
7602
7672
|
const [hasNewStepFormFromRestream, setHasNewStepFormFromRestream] = useState(false);
|
|
7673
|
+
const [activeFormIntent, setActiveFormIntent] = useState(null);
|
|
7603
7674
|
// Refs for accumulating state during streaming (avoids stale closures)
|
|
7604
7675
|
const stepsRef = useRef(stepsState);
|
|
7605
7676
|
const questionsRef = useRef(questionsState);
|
|
@@ -7608,6 +7679,16 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7608
7679
|
const handleChangeTabValue = (_event, newValue) => {
|
|
7609
7680
|
setTabValue(newValue);
|
|
7610
7681
|
};
|
|
7682
|
+
// Switch to agent_response tab when ButtonContent's nth init stream completes with status "completed"
|
|
7683
|
+
useEffect(() => {
|
|
7684
|
+
const handleStepFormCompleted = () => {
|
|
7685
|
+
setTabValue("agent_response");
|
|
7686
|
+
};
|
|
7687
|
+
window.addEventListener("stepFormStreamCompleted", handleStepFormCompleted);
|
|
7688
|
+
return () => {
|
|
7689
|
+
window.removeEventListener("stepFormStreamCompleted", handleStepFormCompleted);
|
|
7690
|
+
};
|
|
7691
|
+
}, []);
|
|
7611
7692
|
// Render a widget item from SSE data
|
|
7612
7693
|
const renderWidget = (item, index) => {
|
|
7613
7694
|
try {
|
|
@@ -7694,9 +7775,11 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7694
7775
|
},
|
|
7695
7776
|
];
|
|
7696
7777
|
}
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7778
|
+
let intentSteps = newQuestionsStepsMap[currentIntent];
|
|
7779
|
+
// Remove placeholder if the real step has a header
|
|
7780
|
+
if (newStep.header && intentSteps.length === 1 && intentSteps[0].header === "Processing Request") {
|
|
7781
|
+
intentSteps = [];
|
|
7782
|
+
newQuestionsStepsMap[currentIntent] = intentSteps;
|
|
7700
7783
|
}
|
|
7701
7784
|
const existingStepIdx = intentSteps.findIndex((s) => s.header === newStep.header);
|
|
7702
7785
|
if (existingStepIdx !== -1) {
|
|
@@ -7730,7 +7813,10 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7730
7813
|
],
|
|
7731
7814
|
},
|
|
7732
7815
|
};
|
|
7733
|
-
newStepFormDataMap[currentIntent] =
|
|
7816
|
+
newStepFormDataMap[currentIntent] = {
|
|
7817
|
+
widgets: [...formWidgetData, submitButton],
|
|
7818
|
+
showSavedFilters: data.show_saved_filters !== false,
|
|
7819
|
+
};
|
|
7734
7820
|
}
|
|
7735
7821
|
}
|
|
7736
7822
|
if (data.status === "widget") {
|
|
@@ -7757,10 +7843,16 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7757
7843
|
setWidgetContent((prev) => [...prev, ...newWidgets]);
|
|
7758
7844
|
}
|
|
7759
7845
|
// If the response contains a new step_form, reset stepFormSubmitted and mark new form as active
|
|
7760
|
-
const
|
|
7761
|
-
if (
|
|
7846
|
+
const lastStepFormChunk = [...chunks].reverse().find((c) => c.status === "step_form");
|
|
7847
|
+
if (lastStepFormChunk) {
|
|
7848
|
+
const formWidgetData = isArray$2(lastStepFormChunk.widget_data) ? lastStepFormChunk.widget_data : [lastStepFormChunk.widget_data];
|
|
7849
|
+
const latestIntent = lastStepFormChunk.current_intent || formWidgetData?.[0]?.current_intent;
|
|
7762
7850
|
setStepFormSubmitted(false);
|
|
7763
7851
|
setHasNewStepFormFromRestream(true);
|
|
7852
|
+
setActiveFormIntent(latestIntent || null);
|
|
7853
|
+
// Clear stale persisted form values and context so the new form starts fresh
|
|
7854
|
+
dispatch(clearPersistedFormValues());
|
|
7855
|
+
dispatch(setChatbotContext({}));
|
|
7764
7856
|
}
|
|
7765
7857
|
setIsRestreaming(false);
|
|
7766
7858
|
}, [stepFormStreamData]);
|
|
@@ -7778,7 +7870,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7778
7870
|
icon: jsx(PsychologyOutlinedIcon, { fontSize: "large" }),
|
|
7779
7871
|
},
|
|
7780
7872
|
], tabPanels: [
|
|
7781
|
-
jsx(Steps, { steps: stepsState, questions: questionsState, questionsStepsMap: questionsStepsMapState, stepFormDataMap: stepFormDataMapState, isFormDisabled:
|
|
7873
|
+
jsx(Steps, { steps: stepsState, questions: questionsState, questionsStepsMap: questionsStepsMapState, stepFormDataMap: stepFormDataMapState, isFormDisabled: (isFormDisabled && !isRestreaming) || stepFormSubmitted, activeFormIntent: hasNewStepFormFromRestream ? activeFormIntent : null, isRestreaming: isRestreaming }),
|
|
7782
7874
|
jsxs(AgentResponse, { children: [children, renderedWidgets.length > 0 && (jsx("div", { className: "restream-widget-content", children: renderedWidgets }))] }),
|
|
7783
7875
|
], value: tabValue }) }));
|
|
7784
7876
|
};
|
|
@@ -11532,6 +11624,36 @@ const SmartBot = (props) => {
|
|
|
11532
11624
|
setFieldNumber,
|
|
11533
11625
|
setAdditionalArgs,
|
|
11534
11626
|
});
|
|
11627
|
+
// Show/hide stop icon when step-form restream (second init API from ButtonContent) starts/ends.
|
|
11628
|
+
// Must live here (SmartBot) because StreamedContent unmounts after the first stream completes.
|
|
11629
|
+
useEffect(() => {
|
|
11630
|
+
const handleStepFormStreamStart = () => {
|
|
11631
|
+
setIsStop(true);
|
|
11632
|
+
const { stepFormStreamControl } = require("./components/message-template/components/message-content/ButtonContent");
|
|
11633
|
+
const abortStepFormStream = () => {
|
|
11634
|
+
if (stepFormStreamControl.abort) {
|
|
11635
|
+
stepFormStreamControl.abort();
|
|
11636
|
+
}
|
|
11637
|
+
setIsStop(false);
|
|
11638
|
+
};
|
|
11639
|
+
setFunctionsState((prev) => ({
|
|
11640
|
+
...prev,
|
|
11641
|
+
abortStreaming: abortStepFormStream,
|
|
11642
|
+
}));
|
|
11643
|
+
if (functionsRef?.current) {
|
|
11644
|
+
functionsRef.current.abortStreaming = abortStepFormStream;
|
|
11645
|
+
}
|
|
11646
|
+
};
|
|
11647
|
+
const handleStepFormStreamEnd = () => {
|
|
11648
|
+
setIsStop(false);
|
|
11649
|
+
};
|
|
11650
|
+
window.addEventListener("stepFormStreamStart", handleStepFormStreamStart);
|
|
11651
|
+
window.addEventListener("stepFormStreamEnd", handleStepFormStreamEnd);
|
|
11652
|
+
return () => {
|
|
11653
|
+
window.removeEventListener("stepFormStreamStart", handleStepFormStreamStart);
|
|
11654
|
+
window.removeEventListener("stepFormStreamEnd", handleStepFormStreamEnd);
|
|
11655
|
+
};
|
|
11656
|
+
}, []);
|
|
11535
11657
|
const fetchCustomBotConfigurations = async () => {
|
|
11536
11658
|
try {
|
|
11537
11659
|
// const response = await fetchCustomBotConfig(baseUrl);
|