impact-chatbot 2.3.43 → 2.3.48
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 +2 -0
- package/dist/components/message-template/components/message-content/tabular-content/index.d.ts +4 -1
- package/dist/index.cjs.js +298 -59
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +298 -59
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -5073,6 +5073,26 @@ 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
|
+
}
|
|
5087
|
+
return new MessageEvent(type, { data: data });
|
|
5088
|
+
}
|
|
5089
|
+
if (parsedData?.status === "notification") {
|
|
5090
|
+
messageToStoreRef.current.notificationData = {
|
|
5091
|
+
message: parsedData?.message || "",
|
|
5092
|
+
chat_id: parsedData?.chat_id || "",
|
|
5093
|
+
session_id: parsedData?.session_id || "",
|
|
5094
|
+
};
|
|
5095
|
+
// Do NOT append notification messages to chatData.response — return early
|
|
5076
5096
|
return new MessageEvent(type, { data: data });
|
|
5077
5097
|
}
|
|
5078
5098
|
if (parsedData?.status === "thinking") {
|
|
@@ -5111,13 +5131,6 @@ const sseevent = (message, messageToStoreRef) => {
|
|
|
5111
5131
|
? parsedData.additional_args
|
|
5112
5132
|
: {};
|
|
5113
5133
|
}
|
|
5114
|
-
if (parsedData?.status === "notification") {
|
|
5115
|
-
messageToStoreRef.current.notificationData = {
|
|
5116
|
-
message: parsedData?.message || "",
|
|
5117
|
-
chat_id: parsedData?.chat_id || "",
|
|
5118
|
-
session_id: parsedData?.session_id || "",
|
|
5119
|
-
};
|
|
5120
|
-
}
|
|
5121
5134
|
if (parsedData?.status === "completed" ||
|
|
5122
5135
|
parsedData?.status === "follow-up") {
|
|
5123
5136
|
messageToStoreRef.current.initValue = true;
|
|
@@ -5273,6 +5286,9 @@ const stepFormStreamControl = {
|
|
|
5273
5286
|
chatId: "",
|
|
5274
5287
|
agentId: "",
|
|
5275
5288
|
baseUrl: "",
|
|
5289
|
+
// Completed/follow-up state — persists across ButtonContent remounts
|
|
5290
|
+
initValue: false,
|
|
5291
|
+
uniqueChatId: "",
|
|
5276
5292
|
};
|
|
5277
5293
|
const useStyles$5 = makeStyles((theme) => ({
|
|
5278
5294
|
buttonContainer: {
|
|
@@ -5335,8 +5351,15 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5335
5351
|
};
|
|
5336
5352
|
const callInitApiStream = (userInput) => {
|
|
5337
5353
|
// Prefer module-level values (set synchronously by StreamedContent), fall back to sessionStorage
|
|
5338
|
-
|
|
5339
|
-
|
|
5354
|
+
// If a previous completed/follow-up response updated the state, use those values.
|
|
5355
|
+
// Read from module-level stepFormStreamControl (survives remounts) instead of local messageStoreRef.
|
|
5356
|
+
const hasCompletedState = stepFormStreamControl.initValue === true;
|
|
5357
|
+
const sessionId = hasCompletedState
|
|
5358
|
+
? (stepFormStreamControl.sessionId ?? "")
|
|
5359
|
+
: (stepFormStreamControl.sessionId || sessionStorage.getItem("stepForm_sessionId") || "");
|
|
5360
|
+
const chatId = hasCompletedState
|
|
5361
|
+
? (stepFormStreamControl.uniqueChatId ?? "")
|
|
5362
|
+
: (stepFormStreamControl.chatId || sessionStorage.getItem("stepForm_chatId") || "");
|
|
5340
5363
|
const agentId = stepFormStreamControl.agentId || sessionStorage.getItem("stepForm_agentId") || "";
|
|
5341
5364
|
const baseUrl = stepFormStreamControl.baseUrl || sessionStorage.getItem("stepForm_baseUrl") || "";
|
|
5342
5365
|
const payload = {
|
|
@@ -5344,9 +5367,14 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5344
5367
|
session_id: sessionId,
|
|
5345
5368
|
chat_id: chatId,
|
|
5346
5369
|
user_input: userInput,
|
|
5347
|
-
init: false,
|
|
5370
|
+
init: hasCompletedState ? true : false,
|
|
5348
5371
|
delay: 0.3,
|
|
5349
5372
|
};
|
|
5373
|
+
// Reset the flag so subsequent calls don't re-use stale completed state
|
|
5374
|
+
if (hasCompletedState) {
|
|
5375
|
+
messageStoreRef.current.initValue = false;
|
|
5376
|
+
stepFormStreamControl.initValue = false;
|
|
5377
|
+
}
|
|
5350
5378
|
const endPoint = baseUrl
|
|
5351
5379
|
? `${BASE_API}${baseUrl}/chatbot/agent/init`
|
|
5352
5380
|
: `${BASE_API}/core/chatbot/agent/init`;
|
|
@@ -5365,10 +5393,10 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5365
5393
|
if (sessionId) {
|
|
5366
5394
|
stopAgentFlow({ session_id: sessionId }, baseUrl);
|
|
5367
5395
|
}
|
|
5368
|
-
dispatch(setStepFormStreamData({ status: "error", chunks: [...chunksRef] }));
|
|
5396
|
+
dispatch(setStepFormStreamData({ status: "error", chunks: [...chunksRef], sessionId }));
|
|
5369
5397
|
};
|
|
5370
5398
|
// Signal that streaming has started (after setting stepFormStreamControl so useEffect sees the flag)
|
|
5371
|
-
dispatch(setStepFormStreamData({ status: "streaming_start", chunks: [] }));
|
|
5399
|
+
dispatch(setStepFormStreamData({ status: "streaming_start", chunks: [], sessionId }));
|
|
5372
5400
|
// Fire DOM event so SmartBot can show stop icon (Redux gets cleared by TabularContent before parent effects run)
|
|
5373
5401
|
window.dispatchEvent(new CustomEvent("stepFormStreamStart"));
|
|
5374
5402
|
sourceRef.current = AxiosSource(endPoint, {
|
|
@@ -5388,24 +5416,40 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5388
5416
|
console.log("[ButtonContent] SSE chunk:", data);
|
|
5389
5417
|
if (data?.status === "step" || data?.status === "step_form" || data?.status === "questions" || data?.status === "thinking" || data?.status === "widget") {
|
|
5390
5418
|
chunksRef.push(data);
|
|
5419
|
+
// Dispatch widget chunks immediately for real-time rendering
|
|
5420
|
+
if (data?.status === "widget") {
|
|
5421
|
+
dispatch(setStepFormStreamData({ status: "widget_chunk", chunks: [data], sessionId }));
|
|
5422
|
+
}
|
|
5391
5423
|
// If this chunk also carries [DONE], dispatch collected chunks now
|
|
5392
5424
|
if (data?.message === "[DONE]") {
|
|
5393
5425
|
stepFormStreamControl.isStreaming = false;
|
|
5394
5426
|
stepFormStreamControl.abort = null;
|
|
5395
5427
|
window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
|
|
5396
|
-
dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef] }));
|
|
5428
|
+
dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef], sessionId }));
|
|
5397
5429
|
}
|
|
5398
5430
|
}
|
|
5399
|
-
else if (data?.status === "completed" || data?.message === "[DONE]") {
|
|
5431
|
+
else if (data?.status === "completed" || data?.status === "follow-up" || data?.message === "[DONE]") {
|
|
5432
|
+
// Update messageStoreRef the same way AxiosEventSource does for completed/follow-up
|
|
5433
|
+
if (data?.status === "completed" || data?.status === "follow-up") {
|
|
5434
|
+
messageStoreRef.current.initValue = true;
|
|
5435
|
+
messageStoreRef.current.sessionId = "";
|
|
5436
|
+
messageStoreRef.current.uniqueChatId = data?.chat_id ? data.chat_id : "";
|
|
5437
|
+
// Also persist on module-level object so it survives ButtonContent remounts
|
|
5438
|
+
stepFormStreamControl.initValue = true;
|
|
5439
|
+
stepFormStreamControl.sessionId = "";
|
|
5440
|
+
stepFormStreamControl.uniqueChatId = data?.chat_id ? data.chat_id : "";
|
|
5441
|
+
}
|
|
5400
5442
|
// Stream ended — dispatch all collected chunks at once
|
|
5401
5443
|
stepFormStreamControl.isStreaming = false;
|
|
5402
5444
|
stepFormStreamControl.abort = null;
|
|
5403
5445
|
window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
|
|
5404
|
-
// Signal tab switch to agent_response when status is "completed"
|
|
5405
|
-
if
|
|
5446
|
+
// Signal tab switch to agent_response when status is "completed",
|
|
5447
|
+
// but only if the response doesn't contain a new step_form that needs user interaction
|
|
5448
|
+
const hasStepForm = chunksRef.some((c) => c.status === "step_form");
|
|
5449
|
+
if (data?.status === "completed" && !hasStepForm) {
|
|
5406
5450
|
window.dispatchEvent(new CustomEvent("stepFormStreamCompleted"));
|
|
5407
5451
|
}
|
|
5408
|
-
dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef] }));
|
|
5452
|
+
dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef], sessionId }));
|
|
5409
5453
|
}
|
|
5410
5454
|
else if (data?.message) {
|
|
5411
5455
|
chunksRef.push({ status: "content", message: data.message });
|
|
@@ -5420,7 +5464,7 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5420
5464
|
stepFormStreamControl.isStreaming = false;
|
|
5421
5465
|
stepFormStreamControl.abort = null;
|
|
5422
5466
|
window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
|
|
5423
|
-
dispatch(setStepFormStreamData({ status: "error", chunks: chunksRef }));
|
|
5467
|
+
dispatch(setStepFormStreamData({ status: "error", chunks: chunksRef, sessionId }));
|
|
5424
5468
|
});
|
|
5425
5469
|
};
|
|
5426
5470
|
const renderButtons = () => {
|
|
@@ -6512,10 +6556,8 @@ const getQuestionStatus$1 = (questionSteps) => {
|
|
|
6512
6556
|
/**
|
|
6513
6557
|
* Renders a single progress bar item (main point + sub-items)
|
|
6514
6558
|
*/
|
|
6515
|
-
const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData, showSavedFilters = true, isFormDisabled,
|
|
6516
|
-
const
|
|
6517
|
-
// When restreaming and this is the last item, show as in-progress
|
|
6518
|
-
const status = (isRestreaming && isLast) ? "in-progress" : baseStatus;
|
|
6559
|
+
const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData, showSavedFilters = true, isFormDisabled, onAllSubItemsAnimated = undefined }) => {
|
|
6560
|
+
const status = getQuestionStatus$1(questionSteps);
|
|
6519
6561
|
const animatedCountRef = useRef(0);
|
|
6520
6562
|
const [isExpanded, setIsExpanded] = useState(true);
|
|
6521
6563
|
const dotClass = status === "completed"
|
|
@@ -6559,8 +6601,14 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
|
|
|
6559
6601
|
const lastQuestionCompleted = lastQuestionSteps &&
|
|
6560
6602
|
lastQuestionSteps.length > 0 &&
|
|
6561
6603
|
lastQuestionSteps.every((s) => s.step_status === "completed");
|
|
6604
|
+
const hasStepFormData = Object.keys(stepFormDataMap).length > 0;
|
|
6562
6605
|
useEffect(() => {
|
|
6563
6606
|
if (done) {
|
|
6607
|
+
// Don't auto-switch to agent_response tab when there's a step form pending user interaction
|
|
6608
|
+
if (hasStepFormData) {
|
|
6609
|
+
setFinalStepDone(true);
|
|
6610
|
+
return;
|
|
6611
|
+
}
|
|
6564
6612
|
if (!finalStepDone) {
|
|
6565
6613
|
if (currentMode === "navigation") {
|
|
6566
6614
|
let updatedSteps = steps.map((step) => ({
|
|
@@ -6610,7 +6658,7 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
|
|
|
6610
6658
|
step_status: "not-completed",
|
|
6611
6659
|
},
|
|
6612
6660
|
];
|
|
6613
|
-
return (jsx("div", { className: classes.progressBarContainer, children: jsx(ProgressBarItem$1, { question: fallbackQuestion, questionSteps: fallbackSteps, isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled
|
|
6661
|
+
return (jsx("div", { className: classes.progressBarContainer, children: jsx(ProgressBarItem$1, { question: fallbackQuestion, questionSteps: fallbackSteps, isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled }) }));
|
|
6614
6662
|
}
|
|
6615
6663
|
return (jsxs("div", { className: classes.progressBarContainer, children: [questions.map((question, index) => {
|
|
6616
6664
|
const questionData = questionsStepsMap[question];
|
|
@@ -6633,17 +6681,40 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
|
|
|
6633
6681
|
}, children: jsx(ProgressBarItem$1, { question: "Thinking", questionSteps: [{ header: "", sub_header: "", step_status: "not-completed" }], isLast: true, classes: classes, formData: null, isFormDisabled: isFormDisabled }) }))] }));
|
|
6634
6682
|
};
|
|
6635
6683
|
|
|
6684
|
+
const renderWidgetItem = (item, index) => {
|
|
6685
|
+
try {
|
|
6686
|
+
const parsedData = parseResponse(item, item.type, "", "", true);
|
|
6687
|
+
if (!parsedData)
|
|
6688
|
+
return null;
|
|
6689
|
+
const key = `streaming-widget-${index}`;
|
|
6690
|
+
switch (parsedData.bodyType) {
|
|
6691
|
+
case "text":
|
|
6692
|
+
return jsx(TextContent, { bodyText: parsedData.bodyText, botData: parsedData }, key);
|
|
6693
|
+
case "table":
|
|
6694
|
+
return jsx(TableContent, { bodyText: parsedData.bodyText }, key);
|
|
6695
|
+
case "graph":
|
|
6696
|
+
return jsx(GraphContent, { bodyText: parsedData.bodyText }, key);
|
|
6697
|
+
default:
|
|
6698
|
+
return null;
|
|
6699
|
+
}
|
|
6700
|
+
}
|
|
6701
|
+
catch (e) {
|
|
6702
|
+
console.error("[AgentResponse] renderWidgetItem error:", e);
|
|
6703
|
+
return null;
|
|
6704
|
+
}
|
|
6705
|
+
};
|
|
6636
6706
|
const AgentResponse$1 = (props) => {
|
|
6637
|
-
const { content, isStreaming } = props;
|
|
6707
|
+
const { content, isStreaming, streamingWidgetData = [] } = props;
|
|
6638
6708
|
const classes = useStyles$4();
|
|
6639
6709
|
const chatClasses = useStyles$7();
|
|
6640
|
-
|
|
6641
|
-
|
|
6642
|
-
|
|
6710
|
+
const renderedWidgets = streamingWidgetData
|
|
6711
|
+
.map((item, index) => renderWidgetItem(item, index))
|
|
6712
|
+
.filter(Boolean);
|
|
6713
|
+
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 }))] }));
|
|
6643
6714
|
};
|
|
6644
6715
|
|
|
6645
6716
|
const StepsResponseTab = (props) => {
|
|
6646
|
-
const { steps, setSteps, stepsDone, setStepsDone, finalStepDone, setFinalStepDone, content, isStreaming, stepChange, currentMode, questions, questionsStepsMap, stepFormDataMap, isFormDisabled, } = props;
|
|
6717
|
+
const { steps, setSteps, stepsDone, setStepsDone, finalStepDone, setFinalStepDone, content, isStreaming, stepChange, currentMode, questions, questionsStepsMap, stepFormDataMap, isFormDisabled, streamingWidgetData, } = props;
|
|
6647
6718
|
const [tabValue, setTabValue] = useState("steps");
|
|
6648
6719
|
const handleChangeTabValue = (_event, newValue) => {
|
|
6649
6720
|
setTabValue(newValue);
|
|
@@ -6661,7 +6732,7 @@ const StepsResponseTab = (props) => {
|
|
|
6661
6732
|
},
|
|
6662
6733
|
], tabPanels: [
|
|
6663
6734
|
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 }),
|
|
6664
|
-
jsx(AgentResponse$1, { content: content, isStreaming: isStreaming }),
|
|
6735
|
+
jsx(AgentResponse$1, { content: content, isStreaming: isStreaming, streamingWidgetData: streamingWidgetData }),
|
|
6665
6736
|
], value: tabValue }) }));
|
|
6666
6737
|
};
|
|
6667
6738
|
|
|
@@ -6711,6 +6782,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
6711
6782
|
// const [thinkingContent, setThinkingContent] = useState("");
|
|
6712
6783
|
const [thinkDone, setThinkDone] = useState(false);
|
|
6713
6784
|
const [isStreaming, setIsStreaming] = useState(true);
|
|
6785
|
+
const [streamingWidgetData, setStreamingWidgetData] = useState([]);
|
|
6714
6786
|
const [thinkingStarted, setThinkingStarted] = useState(false);
|
|
6715
6787
|
const [isStreamingDone, setIsStreamingDone] = useState(false);
|
|
6716
6788
|
const [isThinking, setIsThinking] = useState(false);
|
|
@@ -6885,7 +6957,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
6885
6957
|
}));
|
|
6886
6958
|
return;
|
|
6887
6959
|
}
|
|
6888
|
-
if (data?.message || data?.status === "step" || data?.status === "step_form" || data?.status === "thinking" || data?.status === "questions") {
|
|
6960
|
+
if (data?.message || data?.status === "step" || data?.status === "step_form" || data?.status === "thinking" || data?.status === "questions" || data?.status === "widget") {
|
|
6889
6961
|
if (data.status === "questions") {
|
|
6890
6962
|
const incomingQuestions = data.widget_data?.[0]?.questions || [];
|
|
6891
6963
|
questionsRef.current = incomingQuestions;
|
|
@@ -6998,6 +7070,15 @@ const StreamedContent = ({ botData }) => {
|
|
|
6998
7070
|
: [data.widget_data];
|
|
6999
7071
|
const currentIntent = data.current_intent || formWidgetData?.[0]?.current_intent;
|
|
7000
7072
|
if (currentIntent) {
|
|
7073
|
+
// Auto-create question/intent entry if no prior step chunk created it
|
|
7074
|
+
if (!questionsStepsMapRef.current[currentIntent]) {
|
|
7075
|
+
questionsStepsMapRef.current[currentIntent] = [];
|
|
7076
|
+
if (!questionsRef.current.includes(currentIntent)) {
|
|
7077
|
+
questionsRef.current = [...questionsRef.current, currentIntent];
|
|
7078
|
+
setQuestions([...questionsRef.current]);
|
|
7079
|
+
}
|
|
7080
|
+
setQuestionsStepsMap(cloneDeep(questionsStepsMapRef.current));
|
|
7081
|
+
}
|
|
7001
7082
|
const sendButton = document.getElementById("chat-input-send-button");
|
|
7002
7083
|
const stepFormSubmitButton = {
|
|
7003
7084
|
type: "button",
|
|
@@ -7037,12 +7118,20 @@ const StreamedContent = ({ botData }) => {
|
|
|
7037
7118
|
stepFormStreamControl.baseUrl = _burl;
|
|
7038
7119
|
// If this is the [DONE] chunk, mark streaming as complete
|
|
7039
7120
|
if (data.message === "[DONE]") {
|
|
7121
|
+
setStepsDone(true);
|
|
7040
7122
|
setIsStreamingDone(true);
|
|
7041
7123
|
const doneState = streamStateMap.get(streamKey);
|
|
7042
7124
|
if (doneState)
|
|
7043
7125
|
doneState.completed = true;
|
|
7044
7126
|
}
|
|
7045
7127
|
}
|
|
7128
|
+
else if (data.status === "widget") {
|
|
7129
|
+
// Render widget data immediately as it arrives during streaming
|
|
7130
|
+
const widgetItems = isArray(data.widget_data)
|
|
7131
|
+
? data.widget_data
|
|
7132
|
+
: [data.widget_data];
|
|
7133
|
+
setStreamingWidgetData((prev) => [...prev, ...widgetItems]);
|
|
7134
|
+
}
|
|
7046
7135
|
else if (data.message !== "[DONE]") {
|
|
7047
7136
|
if (!thinkingDoneRef?.current && currentMode === "agent") {
|
|
7048
7137
|
thinkingDoneRef.current = true;
|
|
@@ -7125,6 +7214,13 @@ const StreamedContent = ({ botData }) => {
|
|
|
7125
7214
|
const store = messageToStoreRef.current;
|
|
7126
7215
|
// Restore accumulated content
|
|
7127
7216
|
setContent(store.chatData?.response || "");
|
|
7217
|
+
// Restore widget data received so far
|
|
7218
|
+
if (isArray(store.appendedData) && store.appendedData.length > 0) {
|
|
7219
|
+
setStreamingWidgetData(store.appendedData);
|
|
7220
|
+
}
|
|
7221
|
+
else if (store.appendedData && !isArray(store.appendedData) && Object.keys(store.appendedData).length > 0) {
|
|
7222
|
+
setStreamingWidgetData([store.appendedData]);
|
|
7223
|
+
}
|
|
7128
7224
|
// Restore thinking state
|
|
7129
7225
|
if (store.chatData?.thinkingResponse?.thinkingStream) {
|
|
7130
7226
|
thinkingContentRef.current = store.chatData.thinkingResponse.thinkingStream;
|
|
@@ -7191,15 +7287,21 @@ const StreamedContent = ({ botData }) => {
|
|
|
7191
7287
|
dispatch(setCurrentAgentChatId(messageToStoreRef.current.uniqueChatId));
|
|
7192
7288
|
}
|
|
7193
7289
|
// Persist IDs for step form restream (ButtonContent reads these)
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
|
|
7202
|
-
stepFormStreamControl.
|
|
7290
|
+
const _sid2 = messageToStoreRef.current.sessionId || "";
|
|
7291
|
+
const _cid2 = messageToStoreRef.current.uniqueChatId || "";
|
|
7292
|
+
const _aid2 = botData.inputBody?.agent_id || "";
|
|
7293
|
+
const _burl2 = baseUrl || "";
|
|
7294
|
+
sessionStorage.setItem("stepForm_sessionId", _sid2);
|
|
7295
|
+
sessionStorage.setItem("stepForm_chatId", _cid2);
|
|
7296
|
+
sessionStorage.setItem("stepForm_agentId", _aid2);
|
|
7297
|
+
sessionStorage.setItem("stepForm_baseUrl", _burl2);
|
|
7298
|
+
stepFormStreamControl.sessionId = _sid2;
|
|
7299
|
+
stepFormStreamControl.chatId = _cid2;
|
|
7300
|
+
stepFormStreamControl.agentId = _aid2;
|
|
7301
|
+
stepFormStreamControl.baseUrl = _burl2;
|
|
7302
|
+
// Persist completed/follow-up state so ButtonContent can read it after remount
|
|
7303
|
+
stepFormStreamControl.initValue = messageToStoreRef.current.initValue;
|
|
7304
|
+
stepFormStreamControl.uniqueChatId = _cid2;
|
|
7203
7305
|
let appendedDataLength = 0;
|
|
7204
7306
|
// Use appendedDataFromLastChunk for field number calculation like host app
|
|
7205
7307
|
if (isArray(messageToStoreRef.current.appendedDataFromLastChunk)) {
|
|
@@ -7247,14 +7349,16 @@ const StreamedContent = ({ botData }) => {
|
|
|
7247
7349
|
data: isEmpty(dummyButton)
|
|
7248
7350
|
? [textResponseTobeParsed, ...finalData]
|
|
7249
7351
|
: [textResponseTobeParsed, ...finalData, dummyButton],
|
|
7352
|
+
session_id: messageToStoreRef.current.sessionId || "",
|
|
7250
7353
|
},
|
|
7251
7354
|
},
|
|
7252
7355
|
};
|
|
7356
|
+
const hasStepFormWidgets = !isEmpty(stepFormDataMapRef.current);
|
|
7253
7357
|
processResponse(response, botData.inputBody, currentMode, botData.utilityObject.customChatConfig, {
|
|
7254
7358
|
newChatData: chatDataInfoRef,
|
|
7255
7359
|
isTabEnabled: true,
|
|
7256
7360
|
steps: cloneDeep(stepRef.current),
|
|
7257
|
-
currentTabValue: stepsDone ? "agent_response" :
|
|
7361
|
+
currentTabValue: (stepsDone && !hasStepFormWidgets) ? "agent_response" : "steps",
|
|
7258
7362
|
questions: cloneDeep(questionsRef.current),
|
|
7259
7363
|
questionsStepsMap: cloneDeep(questionsStepsMapRef.current),
|
|
7260
7364
|
stepFormDataMap: { ...stepFormDataMapRef.current },
|
|
@@ -7330,6 +7434,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
7330
7434
|
data: {
|
|
7331
7435
|
data: {
|
|
7332
7436
|
data: [textResponseTobeParsed, ...finalData],
|
|
7437
|
+
session_id: messageToStoreRef.current.sessionId || "",
|
|
7333
7438
|
},
|
|
7334
7439
|
},
|
|
7335
7440
|
};
|
|
@@ -7340,7 +7445,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
7340
7445
|
newChatData: chatDataInfoRef,
|
|
7341
7446
|
isTabEnabled: true,
|
|
7342
7447
|
steps: cloneDeep(stepRef.current),
|
|
7343
|
-
currentTabValue: stepsDone ? "agent_response" :
|
|
7448
|
+
currentTabValue: stepsDone ? "agent_response" : "steps",
|
|
7344
7449
|
questions: cloneDeep(questionsRef.current),
|
|
7345
7450
|
questionsStepsMap: cloneDeep(questionsStepsMapRef.current),
|
|
7346
7451
|
stepFormDataMap: { ...stepFormDataMapRef.current },
|
|
@@ -7487,7 +7592,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
7487
7592
|
* @returns {JSX.Element} Rendered content with optional blinking cursor
|
|
7488
7593
|
*/
|
|
7489
7594
|
const renderContent = () => {
|
|
7490
|
-
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 }) }));
|
|
7595
|
+
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 }) }));
|
|
7491
7596
|
};
|
|
7492
7597
|
if (currentMode === "agent") {
|
|
7493
7598
|
return renderContent();
|
|
@@ -7750,7 +7855,11 @@ const AgentResponse = ({ children }) => {
|
|
|
7750
7855
|
return (jsx("div", { className: classes.agentResponseContainer, children: children }));
|
|
7751
7856
|
};
|
|
7752
7857
|
|
|
7753
|
-
|
|
7858
|
+
// Module-level counter and active instance tracker.
|
|
7859
|
+
// Only the active instance should process stepFormStreamData from Redux.
|
|
7860
|
+
let instanceCounter = 0;
|
|
7861
|
+
let activeTabularInstanceId = null;
|
|
7862
|
+
const TabularContent = ({ steps: initialSteps, currentTabValue, children, questions: initialQuestions = [], questionsStepsMap: initialQuestionsStepsMap = {}, stepFormDataMap: initialStepFormDataMap = {}, isFormDisabled = false, sessionId: propSessionId = "" }) => {
|
|
7754
7863
|
const dispatch = useDispatch();
|
|
7755
7864
|
const stepFormStreamData = useSelector((state) => state.smartBotReducer.stepFormStreamData);
|
|
7756
7865
|
const [tabValue, setTabValue] = useState(currentTabValue);
|
|
@@ -7774,6 +7883,12 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7774
7883
|
const [stepFormSubmitted, setStepFormSubmitted] = useState(false);
|
|
7775
7884
|
const [hasNewStepFormFromRestream, setHasNewStepFormFromRestream] = useState(false);
|
|
7776
7885
|
const [activeFormIntent, setActiveFormIntent] = useState(null);
|
|
7886
|
+
// Stable unique instance ID for this TabularContent mount
|
|
7887
|
+
const instanceIdRef = useRef(null);
|
|
7888
|
+
if (instanceIdRef.current === null) {
|
|
7889
|
+
instanceCounter += 1;
|
|
7890
|
+
instanceIdRef.current = instanceCounter;
|
|
7891
|
+
}
|
|
7777
7892
|
// Refs for accumulating state during streaming (avoids stale closures)
|
|
7778
7893
|
const stepsRef = useRef(stepsState);
|
|
7779
7894
|
const questionsRef = useRef(questionsState);
|
|
@@ -7815,10 +7930,21 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7815
7930
|
return null;
|
|
7816
7931
|
}
|
|
7817
7932
|
};
|
|
7933
|
+
// Register as active instance when this TabularContent has an active step form
|
|
7934
|
+
useEffect(() => {
|
|
7935
|
+
const hasActiveForm = Object.keys(initialStepFormDataMap).length > 0;
|
|
7936
|
+
if (hasActiveForm) {
|
|
7937
|
+
activeTabularInstanceId = instanceIdRef.current;
|
|
7938
|
+
}
|
|
7939
|
+
}, [initialStepFormDataMap]);
|
|
7818
7940
|
// Watch Redux for batched SSE chunks dispatched by ButtonContent
|
|
7819
7941
|
useEffect(() => {
|
|
7820
7942
|
if (!stepFormStreamData)
|
|
7821
7943
|
return;
|
|
7944
|
+
// Only the active instance should process stepFormStreamData
|
|
7945
|
+
if (activeTabularInstanceId !== null && activeTabularInstanceId !== instanceIdRef.current) {
|
|
7946
|
+
return;
|
|
7947
|
+
}
|
|
7822
7948
|
const payload = stepFormStreamData;
|
|
7823
7949
|
// Clear Redux immediately
|
|
7824
7950
|
dispatch(setStepFormStreamData(null));
|
|
@@ -7829,6 +7955,24 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7829
7955
|
setTabValue("steps");
|
|
7830
7956
|
return;
|
|
7831
7957
|
}
|
|
7958
|
+
// Handle real-time widget chunks dispatched immediately by ButtonContent
|
|
7959
|
+
if (payload.status === "widget_chunk") {
|
|
7960
|
+
const chunks = payload.chunks || [];
|
|
7961
|
+
const newWidgets = [];
|
|
7962
|
+
chunks.forEach((data) => {
|
|
7963
|
+
if (data.status === "widget") {
|
|
7964
|
+
const widgetItems = isArray$2(data.widget_data) ? data.widget_data : [data.widget_data];
|
|
7965
|
+
widgetItems.forEach((item) => {
|
|
7966
|
+
if (item)
|
|
7967
|
+
newWidgets.push(item);
|
|
7968
|
+
});
|
|
7969
|
+
}
|
|
7970
|
+
});
|
|
7971
|
+
if (newWidgets.length > 0) {
|
|
7972
|
+
setWidgetContent((prev) => [...prev, ...newWidgets]);
|
|
7973
|
+
}
|
|
7974
|
+
return;
|
|
7975
|
+
}
|
|
7832
7976
|
// Process all collected chunks at once (done or error)
|
|
7833
7977
|
const chunks = payload.chunks || [];
|
|
7834
7978
|
let newSteps = cloneDeep(stepsRef.current);
|
|
@@ -7902,6 +8046,13 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7902
8046
|
const formWidgetData = isArray$2(data.widget_data) ? data.widget_data : [data.widget_data];
|
|
7903
8047
|
const currentIntent = data.current_intent || formWidgetData?.[0]?.current_intent;
|
|
7904
8048
|
if (currentIntent) {
|
|
8049
|
+
// Auto-create question/intent entry if no prior step chunk created it
|
|
8050
|
+
if (!newQuestionsStepsMap[currentIntent]) {
|
|
8051
|
+
newQuestionsStepsMap[currentIntent] = [];
|
|
8052
|
+
if (!newQuestions.includes(currentIntent)) {
|
|
8053
|
+
newQuestions.push(currentIntent);
|
|
8054
|
+
}
|
|
8055
|
+
}
|
|
7905
8056
|
const submitButton = {
|
|
7906
8057
|
type: "button",
|
|
7907
8058
|
data: {
|
|
@@ -7922,13 +8073,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7922
8073
|
};
|
|
7923
8074
|
}
|
|
7924
8075
|
}
|
|
7925
|
-
if (data.status === "widget")
|
|
7926
|
-
const widgetItems = isArray$2(data.widget_data) ? data.widget_data : [data.widget_data];
|
|
7927
|
-
widgetItems.forEach((item) => {
|
|
7928
|
-
if (item)
|
|
7929
|
-
newWidgets.push(item);
|
|
7930
|
-
});
|
|
7931
|
-
}
|
|
8076
|
+
if (data.status === "widget") ;
|
|
7932
8077
|
if (data.status === "content" && data.message) {
|
|
7933
8078
|
newWidgets.push({ type: "text", response: data.message });
|
|
7934
8079
|
}
|
|
@@ -7953,6 +8098,8 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7953
8098
|
setStepFormSubmitted(false);
|
|
7954
8099
|
setHasNewStepFormFromRestream(true);
|
|
7955
8100
|
setActiveFormIntent(latestIntent || null);
|
|
8101
|
+
// Re-register as active instance since this TabularContent now owns the new form
|
|
8102
|
+
activeTabularInstanceId = instanceIdRef.current;
|
|
7956
8103
|
// Clear stale persisted form values and context so the new form starts fresh
|
|
7957
8104
|
dispatch(clearPersistedFormValues());
|
|
7958
8105
|
dispatch(setChatbotContext({}));
|
|
@@ -7977,6 +8124,10 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7977
8124
|
jsxs(AgentResponse, { children: [children, renderedWidgets.length > 0 && (jsx("div", { className: "restream-widget-content", children: renderedWidgets }))] }),
|
|
7978
8125
|
], value: tabValue }) }));
|
|
7979
8126
|
};
|
|
8127
|
+
/** Reset the active instance tracker (call when a new conversation starts from the input field) */
|
|
8128
|
+
const resetActiveTabularInstance = () => {
|
|
8129
|
+
activeTabularInstanceId = null;
|
|
8130
|
+
};
|
|
7980
8131
|
|
|
7981
8132
|
const CombinedContent = ({ botData, props }) => {
|
|
7982
8133
|
const isFormDisabled = botData?.isFormDisabled || false;
|
|
@@ -8045,7 +8196,7 @@ const CombinedContent = ({ botData, props }) => {
|
|
|
8045
8196
|
const validContent = renderedContent.filter(content => content !== null);
|
|
8046
8197
|
const renderCombinedContent = () => (jsx("div", { className: "combined-content-container", children: validContent.length > 0 ? (validContent.map((content, index) => (jsx("div", { className: "combined-content-item", children: content }, `wrapper-${index}`)))) : (jsx("div", { children: "No valid content to display" })) }));
|
|
8047
8198
|
if (isTabEnabled) {
|
|
8048
|
-
return (jsx(TabularContent, { steps: botData?.utilityData?.steps || [], currentTabValue: botData?.utilityData?.currentTabValue || "steps", questions: botData?.utilityData?.questions || [], questionsStepsMap: botData?.utilityData?.questionsStepsMap || {}, stepFormDataMap: botData?.utilityData?.stepFormDataMap || {}, isFormDisabled: isFormDisabled, children: renderCombinedContent() }));
|
|
8199
|
+
return (jsx(TabularContent, { steps: botData?.utilityData?.steps || [], currentTabValue: botData?.utilityData?.currentTabValue || "steps", questions: botData?.utilityData?.questions || [], questionsStepsMap: botData?.utilityData?.questionsStepsMap || {}, stepFormDataMap: botData?.utilityData?.stepFormDataMap || {}, isFormDisabled: isFormDisabled, sessionId: botData?.sessionId || "", children: renderCombinedContent() }));
|
|
8049
8200
|
}
|
|
8050
8201
|
return renderCombinedContent();
|
|
8051
8202
|
};
|
|
@@ -10552,7 +10703,21 @@ const ChatbotInput = (props) => {
|
|
|
10552
10703
|
if (newChatScreen) {
|
|
10553
10704
|
clearFilterValuesCache();
|
|
10554
10705
|
}
|
|
10706
|
+
// Auto-focus editor on mount
|
|
10707
|
+
setTimeout(() => {
|
|
10708
|
+
if (editorRef.current) {
|
|
10709
|
+
editorRef.current.focus();
|
|
10710
|
+
}
|
|
10711
|
+
}, 100);
|
|
10555
10712
|
}, []);
|
|
10713
|
+
// Effect: Re-focus editor when filter set changes (e.g. chip cleared)
|
|
10714
|
+
useEffect(() => {
|
|
10715
|
+
setTimeout(() => {
|
|
10716
|
+
if (editorRef.current) {
|
|
10717
|
+
editorRef.current.focus();
|
|
10718
|
+
}
|
|
10719
|
+
}, 50);
|
|
10720
|
+
}, [selectedFilterSet]);
|
|
10556
10721
|
// Effect: Cleanup tooltips on unmount
|
|
10557
10722
|
useEffect(() => {
|
|
10558
10723
|
return () => {
|
|
@@ -10762,7 +10927,8 @@ const ChatbotInput = (props) => {
|
|
|
10762
10927
|
!target.closest("button") &&
|
|
10763
10928
|
!target.closest(".chat-actions") &&
|
|
10764
10929
|
!target.closest(".filter-set-trigger-wrapper") &&
|
|
10765
|
-
!target.closest(".filter-set-chip-clear")
|
|
10930
|
+
!target.closest(".filter-set-chip-clear") &&
|
|
10931
|
+
!target.closest(".mention-select-wrapper")) {
|
|
10766
10932
|
editorRef.current.focus();
|
|
10767
10933
|
}
|
|
10768
10934
|
}, 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: () => {
|
|
@@ -11551,10 +11717,13 @@ const useStyles = makeStyles({
|
|
|
11551
11717
|
buttonWrapper: {
|
|
11552
11718
|
marginTop: "16px",
|
|
11553
11719
|
},
|
|
11720
|
+
hidden: {
|
|
11721
|
+
display: "none",
|
|
11722
|
+
},
|
|
11554
11723
|
});
|
|
11555
11724
|
const ChatbotSaveFilterComponent = (props) => {
|
|
11556
11725
|
const classes = useStyles();
|
|
11557
|
-
const { savedFilterSets } = props;
|
|
11726
|
+
const { savedFilterSets, partialClose, chatBotWidth } = props;
|
|
11558
11727
|
const [showFilter, setShowFilter] = useState(!isEmpty$1(savedFilterSets));
|
|
11559
11728
|
/**
|
|
11560
11729
|
* onFilterDashboardClick function is called when we click the apply filter
|
|
@@ -11588,6 +11757,12 @@ const ChatbotSaveFilterComponent = (props) => {
|
|
|
11588
11757
|
setShowFilter(true);
|
|
11589
11758
|
}
|
|
11590
11759
|
}, [savedFilterSets]);
|
|
11760
|
+
useEffect(() => {
|
|
11761
|
+
const drawer = document.querySelector(".MuiModal-root.MuiDrawer-root");
|
|
11762
|
+
if (drawer) {
|
|
11763
|
+
drawer.style.display = partialClose ? "none" : "";
|
|
11764
|
+
}
|
|
11765
|
+
}, [partialClose]);
|
|
11591
11766
|
useEffect(() => {
|
|
11592
11767
|
if (!showFilter)
|
|
11593
11768
|
return;
|
|
@@ -11621,11 +11796,13 @@ const ChatbotSaveFilterComponent = (props) => {
|
|
|
11621
11796
|
}
|
|
11622
11797
|
const filterContainer = document.querySelector(".impact_drawer_filter_container.impact_drawer_filter_container_large");
|
|
11623
11798
|
if (filterContainer) {
|
|
11624
|
-
|
|
11799
|
+
const computedWidth = chatBotWidth ? `${chatBotWidth - 86}px` : "616px";
|
|
11800
|
+
filterContainer.style.setProperty("width", computedWidth);
|
|
11625
11801
|
}
|
|
11626
11802
|
const rightPanel = document.querySelector(".impact_drawer_filter_container .impact_drawer_filter_container_right_panel");
|
|
11627
11803
|
if (rightPanel) {
|
|
11628
11804
|
rightPanel.style.setProperty("height", "600px");
|
|
11805
|
+
rightPanel.style.setProperty("width", "100%");
|
|
11629
11806
|
}
|
|
11630
11807
|
const backdrop = document.querySelector(".MuiBackdrop-root.MuiModal-backdrop");
|
|
11631
11808
|
if (backdrop) {
|
|
@@ -11659,8 +11836,8 @@ const ChatbotSaveFilterComponent = (props) => {
|
|
|
11659
11836
|
const observer = new MutationObserver(patchDrawer);
|
|
11660
11837
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
11661
11838
|
return () => observer.disconnect();
|
|
11662
|
-
}, [showFilter]);
|
|
11663
|
-
return (jsx(
|
|
11839
|
+
}, [showFilter, chatBotWidth]);
|
|
11840
|
+
return (jsx("div", { className: partialClose ? classes.hidden : undefined, children: !showFilter ?
|
|
11664
11841
|
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" }) })] }) :
|
|
11665
11842
|
jsx("div", { children: jsx(CoreComponentScreen, { showPageHeader: false,
|
|
11666
11843
|
// Filter dashboard props
|
|
@@ -11693,6 +11870,7 @@ const SmartBot = (props) => {
|
|
|
11693
11870
|
// Per-mode conversation ID tracking — prevents cross-mode contamination when
|
|
11694
11871
|
// switching tabs while streams are pending.
|
|
11695
11872
|
useRef({});
|
|
11873
|
+
const activeConversationIdRef = useRef(activeConversationId);
|
|
11696
11874
|
const activeTab = useRef({
|
|
11697
11875
|
activeTab: "dashboard",
|
|
11698
11876
|
});
|
|
@@ -11711,6 +11889,7 @@ const SmartBot = (props) => {
|
|
|
11711
11889
|
const [filterOptions, setFilterOptions] = useState([]);
|
|
11712
11890
|
const [savedFilterSets, setSavedFilterSets$1] = useState([]);
|
|
11713
11891
|
const [selectedFilterSet, setSelectedFilterSet] = useState(null);
|
|
11892
|
+
const [chatBotWidth, setChatBotWidth] = useState(null);
|
|
11714
11893
|
useRef(0);
|
|
11715
11894
|
const { setUserFlow, setUserScreenAndFlow, fetchUserResultsFromQuery, getCurrentDateTimeString, setLink, } = useChatFlow(chatDataRef, setLoader, setFlowType, setScreenName, setUserInput, setQuestionIndex, setCurrentAppLink, flowType, screenName, questionIndex, userInput, dateFormat, currentMode, activeConversationId, setIsModuleChanged, chatBodyRef, filterReducerState, dispatch, navigate, setShowChatPlaceholder, baseUrl, setChatDataState, setCurrentSessionId, customChatConfig, chatDataInfoRef, chatbotContext, setInitValue, setSessionId, thinkingContent, setThinkingContent, isThinking, setIsThinking, chatId, setChatId, isStop, setIsStop, functionsRef, functionsState, setFunctionsState, thinkingHeaderMessage, setThinkingHeaderMessage, uniqueChatId, initValue, sessionId, fieldNumber, setFieldNumber, additionalArgs, setActiveConversationId, navSessionId, setNavSessionId);
|
|
11716
11895
|
const { parseSavedFlow, saveCurrentChanges, endCurrentSession, clearChatSession, initiateNewChat, hasUnsavedChanges, } = useChatSession(chatDataRef, setFlowType, setScreenName, setUserInput, setTemplateData, chatDataScreenLinkRef, setShowModal, setMinimizedMode, setSelectedModule, setChatDataState, currentMode, setUserFlow, getCurrentDateTimeString, setCurrentAppLink, selectedModule, fetchUserResultsFromQuery, props.closeBot, activeConversationId, setActiveConversationId, setShowChatPlaceholder);
|
|
@@ -11743,6 +11922,10 @@ const SmartBot = (props) => {
|
|
|
11743
11922
|
setFieldNumber,
|
|
11744
11923
|
setAdditionalArgs,
|
|
11745
11924
|
});
|
|
11925
|
+
// Keep activeConversationIdRef in sync so event handlers with [] deps can access the latest value
|
|
11926
|
+
useEffect(() => {
|
|
11927
|
+
activeConversationIdRef.current = activeConversationId;
|
|
11928
|
+
}, [activeConversationId]);
|
|
11746
11929
|
// Show/hide stop icon when step-form restream (second init API from ButtonContent) starts/ends.
|
|
11747
11930
|
// Must live here (SmartBot) because StreamedContent unmounts after the first stream completes.
|
|
11748
11931
|
useEffect(() => {
|
|
@@ -11764,6 +11947,23 @@ const SmartBot = (props) => {
|
|
|
11764
11947
|
};
|
|
11765
11948
|
const handleStepFormStreamEnd = () => {
|
|
11766
11949
|
setIsStop(false);
|
|
11950
|
+
// Update the timestamp on the last bot message to reflect when the restream completed
|
|
11951
|
+
try {
|
|
11952
|
+
const mode = localStorage.getItem("currentModeData") || "agent";
|
|
11953
|
+
const convId = activeConversationIdRef.current;
|
|
11954
|
+
const messages = chatDataInfoRef?.current?.[mode]?.conversations?.[convId]?.messages;
|
|
11955
|
+
if (messages && messages.length > 0) {
|
|
11956
|
+
const lastBotIdx = messages.reduce((lastIdx, msg, idx) => msg.userType === "bot" ? idx : lastIdx, -1);
|
|
11957
|
+
if (lastBotIdx !== -1) {
|
|
11958
|
+
messages[lastBotIdx].timeStamp = moment().format(dateFormat);
|
|
11959
|
+
// Trigger re-render so the UI reflects the updated timestamp
|
|
11960
|
+
setChatDataState((prev) => ({ ...prev }));
|
|
11961
|
+
}
|
|
11962
|
+
}
|
|
11963
|
+
}
|
|
11964
|
+
catch (e) {
|
|
11965
|
+
console.error("Error updating timestamp after step form stream:", e);
|
|
11966
|
+
}
|
|
11767
11967
|
};
|
|
11768
11968
|
window.addEventListener("stepFormStreamStart", handleStepFormStreamStart);
|
|
11769
11969
|
window.addEventListener("stepFormStreamEnd", handleStepFormStreamEnd);
|
|
@@ -12069,7 +12269,6 @@ const SmartBot = (props) => {
|
|
|
12069
12269
|
newMessage.utilityObject = originalUtilityObject;
|
|
12070
12270
|
}
|
|
12071
12271
|
message.jsx = (jsx(BotMessage, { botData: newMessage, state: loadingState, handleLikeDislike: handleLikeDislike, props: properties }));
|
|
12072
|
-
message.firstMessage = true;
|
|
12073
12272
|
let actualProps = {
|
|
12074
12273
|
botData: newMessage,
|
|
12075
12274
|
state: loadingState,
|
|
@@ -12077,6 +12276,7 @@ const SmartBot = (props) => {
|
|
|
12077
12276
|
props: properties,
|
|
12078
12277
|
};
|
|
12079
12278
|
message.actualProps = actualProps;
|
|
12279
|
+
message.firstMessage = true;
|
|
12080
12280
|
// message.enableLikes = true;
|
|
12081
12281
|
}
|
|
12082
12282
|
});
|
|
@@ -12200,6 +12400,9 @@ const SmartBot = (props) => {
|
|
|
12200
12400
|
};
|
|
12201
12401
|
const onSendIconClick = (params, params2) => {
|
|
12202
12402
|
try {
|
|
12403
|
+
// Reset step form stream state so old TabularContent instances don't process new data
|
|
12404
|
+
dispatch(setStepFormStreamData(null));
|
|
12405
|
+
resetActiveTabularInstance();
|
|
12203
12406
|
// dispatch(setChatbotContext({}));
|
|
12204
12407
|
setUserInput(params?.text);
|
|
12205
12408
|
handleSendMessage(params?.text, params?.userExplicitInput, params?.textWithColumnNames);
|
|
@@ -12366,6 +12569,8 @@ const SmartBot = (props) => {
|
|
|
12366
12569
|
localStorage.setItem("isStreaming", "false");
|
|
12367
12570
|
dispatch(setChatbotContext({}));
|
|
12368
12571
|
dispatch(clearPersistedFormValues());
|
|
12572
|
+
dispatch(setStepFormStreamData(null));
|
|
12573
|
+
resetActiveTabularInstance();
|
|
12369
12574
|
setConversation([]);
|
|
12370
12575
|
chatDataInfoRef.current[currentMode] = {
|
|
12371
12576
|
conversations: {},
|
|
@@ -12515,18 +12720,50 @@ const SmartBot = (props) => {
|
|
|
12515
12720
|
// isActive: activeTab.current.activeTab === "agent",
|
|
12516
12721
|
// initialClick: true,
|
|
12517
12722
|
onClick: (params) => {
|
|
12723
|
+
// if (localStorage.getItem("isStreaming") === "true") {
|
|
12724
|
+
// displaySnackMessages(
|
|
12725
|
+
// "Please wait till the current request is completed",
|
|
12726
|
+
// "warning"
|
|
12727
|
+
// );
|
|
12728
|
+
// return;
|
|
12729
|
+
// } else {
|
|
12730
|
+
// const agentConversations = chatDataInfoRef?.current[params?.name?.toLowerCase()]?.conversations;
|
|
12731
|
+
// const firstConversationId = agentConversations ? Object.keys(agentConversations)[0] : undefined;
|
|
12518
12732
|
if (params?.name?.toLowerCase() === "saved filters") {
|
|
12519
12733
|
setNewChatScreen(false);
|
|
12520
12734
|
setShowChatPlaceholder(false);
|
|
12521
12735
|
setShowSavedFilters(true);
|
|
12736
|
+
// if (
|
|
12737
|
+
// !isEmpty(
|
|
12738
|
+
// agentConversations?.[firstConversationId]?.messages
|
|
12739
|
+
// )
|
|
12740
|
+
// ) {
|
|
12741
|
+
// setShowChatPlaceholder(false);
|
|
12742
|
+
// } else {
|
|
12743
|
+
// setShowChatPlaceholder(true);
|
|
12744
|
+
// }
|
|
12522
12745
|
}
|
|
12746
|
+
// setCurrentMode(params?.name?.toLowerCase());
|
|
12747
|
+
// if (firstConversationId) {
|
|
12748
|
+
// setActiveConversationId(firstConversationId);
|
|
12749
|
+
// }
|
|
12750
|
+
// localStorage.setItem(
|
|
12751
|
+
// "currentModeData",
|
|
12752
|
+
// params?.name?.toLowerCase()
|
|
12753
|
+
// );
|
|
12754
|
+
// setNewChatScreen(false);
|
|
12755
|
+
// activeTab.current.activeTab = "agent";
|
|
12756
|
+
// setIsStop(false);
|
|
12757
|
+
// }
|
|
12758
|
+
// setConversation([]);
|
|
12759
|
+
// chatDataInfoRef.current[currentMode] = [];
|
|
12523
12760
|
},
|
|
12524
12761
|
icon: jsx(SvgSaveFilterTab, {}),
|
|
12525
12762
|
},
|
|
12526
12763
|
], utilityList: utilityList, isAssistantThinking: false, isCustomScreen: showChatPlaceholder ? showChatPlaceholder : showSavedFilters, customScreenJsx: showChatPlaceholder ?
|
|
12527
12764
|
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 })
|
|
12528
12765
|
:
|
|
12529
|
-
jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
|
|
12766
|
+
jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets, partialClose: partialClose, chatBotWidth: chatBotWidth }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
|
|
12530
12767
|
freeTextHeading: "Try adding more details :",
|
|
12531
12768
|
freeTextContent: "Alan works better when you provide more context and pointed questions",
|
|
12532
12769
|
}, isStopIcon: isStop, onStopIconClick: onStopIconClick, footerText: "AI-generated responses may contain errors\u2014please verify important information", showSuggestionBanner: showSavedFilters ? false : showSuggestionBanner, onCloseSuggestionBanner: () => {
|
|
@@ -12546,7 +12783,9 @@ const SmartBot = (props) => {
|
|
|
12546
12783
|
}, handleSaveChat: () => {
|
|
12547
12784
|
// Handle save chat logic here
|
|
12548
12785
|
saveCurrentChat();
|
|
12549
|
-
}
|
|
12786
|
+
}, onChatBotResize: (params) => {
|
|
12787
|
+
setChatBotWidth(params);
|
|
12788
|
+
}, onMinimiseChatBot: null })] }));
|
|
12550
12789
|
};
|
|
12551
12790
|
|
|
12552
12791
|
export { SmartBot as default };
|