impact-chatbot 2.3.51 → 2.3.53
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.cjs.js +180 -48
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +181 -49
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -28,6 +28,7 @@ var styled = require('styled-components');
|
|
|
28
28
|
var material = require('@mui/material');
|
|
29
29
|
var utils = require('core/Utils/functions/utils');
|
|
30
30
|
var impactUiV3 = require('impact-ui-v3');
|
|
31
|
+
var axios = require('axios');
|
|
31
32
|
var isArray$1 = require('lodash/isArray');
|
|
32
33
|
var chatbotServices = require('core/commonComponents/smartBot/services/chatbot-services');
|
|
33
34
|
var AgGridComponent = require('core/Utils/agGrid');
|
|
@@ -1299,12 +1300,70 @@ const ThinkingIndicator = (props) => {
|
|
|
1299
1300
|
return (jsxRuntime.jsx("div", { children: jsxRuntime.jsx("div", { children: thinkingContentState ? (jsxRuntime.jsx("div", { children: jsxRuntime.jsx(TextRenderer, { text: thinkingContentState, thinking: true }) })) : (jsxRuntime.jsxs("div", { className: classes.thinkingSpinner, children: [jsxRuntime.jsx("span", { className: classes.thinkingDot }), jsxRuntime.jsx("span", { className: classes.thinkingDot }), jsxRuntime.jsx("span", { className: classes.thinkingDot })] })) }) }));
|
|
1300
1301
|
};
|
|
1301
1302
|
|
|
1303
|
+
/**
|
|
1304
|
+
* Formats elapsed seconds into "Xm:Ys" display string.
|
|
1305
|
+
* e.g. 0 -> "0m:00s", 65 -> "1m:05s", 130 -> "2m:10s"
|
|
1306
|
+
*/
|
|
1307
|
+
const formatElapsedTime = (totalSeconds) => {
|
|
1308
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
1309
|
+
const seconds = totalSeconds % 60;
|
|
1310
|
+
return `${minutes}m:${String(seconds).padStart(2, '0')}s`;
|
|
1311
|
+
};
|
|
1302
1312
|
const ThinkinHeaderInfo = (props) => {
|
|
1303
1313
|
const thinkingContext = reactRedux.useSelector((state) => {
|
|
1304
1314
|
return state.smartBotReducer.thinkingContext;
|
|
1305
1315
|
});
|
|
1306
|
-
const { thinkingHeaderMessage } = thinkingContext;
|
|
1307
|
-
|
|
1316
|
+
const { streamStartTime, isStreamCompleted, finalElapsedSeconds, thinkingHeaderMessage } = thinkingContext;
|
|
1317
|
+
const [elapsed, setElapsed] = React.useState(0);
|
|
1318
|
+
const intervalRef = React.useRef(null);
|
|
1319
|
+
// Once this instance sees "completed", freeze it permanently so a future
|
|
1320
|
+
// chat's streamStartTime doesn't cause it to start ticking again.
|
|
1321
|
+
const frozenRef = React.useRef(false);
|
|
1322
|
+
const frozenTextRef = React.useRef(null);
|
|
1323
|
+
React.useEffect(() => {
|
|
1324
|
+
// If already frozen, ignore all future Redux changes
|
|
1325
|
+
if (frozenRef.current)
|
|
1326
|
+
return;
|
|
1327
|
+
// Clear any existing interval
|
|
1328
|
+
if (intervalRef.current) {
|
|
1329
|
+
clearInterval(intervalRef.current);
|
|
1330
|
+
intervalRef.current = null;
|
|
1331
|
+
}
|
|
1332
|
+
if (isStreamCompleted && typeof finalElapsedSeconds === 'number') {
|
|
1333
|
+
// Freeze this instance — it will never tick again
|
|
1334
|
+
frozenRef.current = true;
|
|
1335
|
+
frozenTextRef.current = `Completed in ${formatElapsedTime(finalElapsedSeconds)}`;
|
|
1336
|
+
setElapsed(finalElapsedSeconds);
|
|
1337
|
+
}
|
|
1338
|
+
else if (streamStartTime && !isStreamCompleted) {
|
|
1339
|
+
// Live timer — update every second
|
|
1340
|
+
const tick = () => {
|
|
1341
|
+
const now = Date.now();
|
|
1342
|
+
const diffSeconds = Math.floor((now - streamStartTime) / 1000);
|
|
1343
|
+
setElapsed(diffSeconds);
|
|
1344
|
+
};
|
|
1345
|
+
tick(); // immediate first tick
|
|
1346
|
+
intervalRef.current = setInterval(tick, 1000);
|
|
1347
|
+
}
|
|
1348
|
+
return () => {
|
|
1349
|
+
if (intervalRef.current) {
|
|
1350
|
+
clearInterval(intervalRef.current);
|
|
1351
|
+
intervalRef.current = null;
|
|
1352
|
+
}
|
|
1353
|
+
};
|
|
1354
|
+
}, [streamStartTime, isStreamCompleted, finalElapsedSeconds]);
|
|
1355
|
+
// Determine display text
|
|
1356
|
+
let displayText = thinkingHeaderMessage || '';
|
|
1357
|
+
if (frozenRef.current && frozenTextRef.current) {
|
|
1358
|
+
displayText = frozenTextRef.current;
|
|
1359
|
+
}
|
|
1360
|
+
else if (streamStartTime && !isStreamCompleted) {
|
|
1361
|
+
displayText = `Working for ${formatElapsedTime(elapsed)}`;
|
|
1362
|
+
}
|
|
1363
|
+
else if (isStreamCompleted && typeof finalElapsedSeconds === 'number') {
|
|
1364
|
+
displayText = `Completed in ${formatElapsedTime(finalElapsedSeconds)}`;
|
|
1365
|
+
}
|
|
1366
|
+
return (jsxRuntime.jsx("div", { className: "thinkin-header-info", children: displayText }));
|
|
1308
1367
|
};
|
|
1309
1368
|
|
|
1310
1369
|
// import { exampleGraphData } from "../examples/GraphExample";
|
|
@@ -4074,7 +4133,7 @@ const useChatState = () => {
|
|
|
4074
4133
|
const [chatId, setChatId] = React.useState("");
|
|
4075
4134
|
const [isStop, setIsStop] = React.useState(false);
|
|
4076
4135
|
const [functionsState, setFunctionsState] = React.useState({});
|
|
4077
|
-
const [thinkingHeaderMessage, setThinkingHeaderMessage] = React.useState("
|
|
4136
|
+
const [thinkingHeaderMessage, setThinkingHeaderMessage] = React.useState("Working… 0m:00s");
|
|
4078
4137
|
const [legacyAgentScreen, setLegacyAgentScreen] = React.useState(false);
|
|
4079
4138
|
const [uniqueChatId, setUniqueChatId] = React.useState("");
|
|
4080
4139
|
const [fieldNumber, setFieldNumber] = React.useState(0);
|
|
@@ -5299,9 +5358,9 @@ const AxiosSource = (url, opts, messageToStoreRef) => {
|
|
|
5299
5358
|
headers: opts.headers,
|
|
5300
5359
|
data: opts.body,
|
|
5301
5360
|
signal: controller.signal,
|
|
5302
|
-
responseType: "
|
|
5361
|
+
responseType: "text",
|
|
5303
5362
|
onDownloadProgress: (progressEvent) => {
|
|
5304
|
-
const response = progressEvent.currentTarget;
|
|
5363
|
+
const response = progressEvent.currentTarget || progressEvent.target;
|
|
5305
5364
|
// Emit 'open' event when the connection is first established
|
|
5306
5365
|
if (!progressEvent.loaded) {
|
|
5307
5366
|
eventTarget.dispatchEvent(new Event("open", {
|
|
@@ -5336,8 +5395,9 @@ const AxiosSource = (url, opts, messageToStoreRef) => {
|
|
|
5336
5395
|
})
|
|
5337
5396
|
.catch((error) => {
|
|
5338
5397
|
let reason = "Network request failed";
|
|
5398
|
+
console.error("[AxiosSource] Request failed:", error);
|
|
5339
5399
|
// Determine specific error reasons
|
|
5340
|
-
if (
|
|
5400
|
+
if (axios.isCancel(error)) {
|
|
5341
5401
|
reason = "Network request aborted";
|
|
5342
5402
|
}
|
|
5343
5403
|
else if (error.code === "ECONNABORTED") {
|
|
@@ -5408,6 +5468,7 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5408
5468
|
status: "",
|
|
5409
5469
|
});
|
|
5410
5470
|
const chatbotContext = reactRedux.useSelector((state) => state.smartBotReducer.chatbotContext);
|
|
5471
|
+
const thinkingContext = reactRedux.useSelector((state) => state.smartBotReducer.thinkingContext);
|
|
5411
5472
|
const handleButtonClick = (button) => {
|
|
5412
5473
|
if (isStepFormSubmit) {
|
|
5413
5474
|
// Build the user_input from chatbotContext
|
|
@@ -5422,7 +5483,6 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5422
5483
|
: typeof value === 'number' ? value : String(value);
|
|
5423
5484
|
}
|
|
5424
5485
|
}
|
|
5425
|
-
console.log("[ButtonContent] step form submit, calling init API with userInput:", userInput);
|
|
5426
5486
|
dispatch(smartBotActions.setChatbotContext({}));
|
|
5427
5487
|
// Call the init API via SSE directly
|
|
5428
5488
|
callInitApiStream(userInput);
|
|
@@ -5481,6 +5541,9 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5481
5541
|
dispatch(smartBotActions.setStepFormStreamData({ status: "streaming_start", chunks: [], sessionId }));
|
|
5482
5542
|
// Fire DOM event so SmartBot can show stop icon (Redux gets cleared by TabularContent before parent effects run)
|
|
5483
5543
|
window.dispatchEvent(new CustomEvent("stepFormStreamStart"));
|
|
5544
|
+
// Capture start time for computing elapsed on completion.
|
|
5545
|
+
// Timer keeps running from the original streamStartTime (set when first API was hit).
|
|
5546
|
+
const stepFormStreamStartTime = Date.now();
|
|
5484
5547
|
sourceRef.current = AxiosSource(endPoint, {
|
|
5485
5548
|
method: "POST",
|
|
5486
5549
|
headers: {
|
|
@@ -5495,7 +5558,6 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5495
5558
|
sourceRef.current.addEventListener("message", (event) => {
|
|
5496
5559
|
try {
|
|
5497
5560
|
const data = JSON.parse(event.data);
|
|
5498
|
-
console.log("[ButtonContent] SSE chunk:", data);
|
|
5499
5561
|
// Always keep stepFormStreamControl.sessionId in sync with the latest chunk's session_id
|
|
5500
5562
|
if (data?.session_id) {
|
|
5501
5563
|
stepFormStreamControl.sessionId = data.session_id;
|
|
@@ -5536,6 +5598,22 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5536
5598
|
stepFormStreamControl.isStreaming = false;
|
|
5537
5599
|
stepFormStreamControl.abort = null;
|
|
5538
5600
|
window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
|
|
5601
|
+
// Stop the timer only when status:"completed" is received
|
|
5602
|
+
if (data?.status === "completed") {
|
|
5603
|
+
// Use the original streamStartTime from Redux (set when first API was hit)
|
|
5604
|
+
const originalStartTime = thinkingContext?.streamStartTime || stepFormStreamStartTime;
|
|
5605
|
+
const totalElapsed = Math.floor((Date.now() - originalStartTime) / 1000);
|
|
5606
|
+
const sfMin = Math.floor(totalElapsed / 60);
|
|
5607
|
+
const sfSec = totalElapsed % 60;
|
|
5608
|
+
const sfWorkedLabel = `Completed in ${sfMin}m:${String(sfSec).padStart(2, '0')}s`;
|
|
5609
|
+
dispatch(smartBotActions.setThinkingContext({
|
|
5610
|
+
streamStartTime: originalStartTime,
|
|
5611
|
+
isStreamCompleted: true,
|
|
5612
|
+
finalElapsedSeconds: totalElapsed,
|
|
5613
|
+
thinkingHeaderMessage: sfWorkedLabel,
|
|
5614
|
+
thinkingContent: "",
|
|
5615
|
+
}));
|
|
5616
|
+
}
|
|
5539
5617
|
// Signal tab switch to agent_response when status is "completed",
|
|
5540
5618
|
// but only if the response doesn't contain a new step_form that needs user interaction
|
|
5541
5619
|
const hasStepForm = chunksRef.some((c) => c.status === "step_form");
|
|
@@ -6994,24 +7072,6 @@ function clearTabNotification() {
|
|
|
6994
7072
|
* This survives the cloneDeep replacement of botData in SmartBot's useEffect.
|
|
6995
7073
|
*/
|
|
6996
7074
|
const streamStateMap = new Map();
|
|
6997
|
-
/**
|
|
6998
|
-
* Formats thinking time to display minutes when appropriate
|
|
6999
|
-
* @param {number} seconds - Time in seconds
|
|
7000
|
-
* @returns {string} Formatted time string
|
|
7001
|
-
*/
|
|
7002
|
-
const formatThinkingTime = (seconds) => {
|
|
7003
|
-
if (seconds < 60) {
|
|
7004
|
-
return `${seconds} second${seconds !== 1 ? 's' : ''}`;
|
|
7005
|
-
}
|
|
7006
|
-
const minutes = Math.floor(seconds / 60);
|
|
7007
|
-
const remainingSeconds = seconds % 60;
|
|
7008
|
-
if (remainingSeconds === 0) {
|
|
7009
|
-
return `${minutes} minute${minutes !== 1 ? 's' : ''}`;
|
|
7010
|
-
}
|
|
7011
|
-
else {
|
|
7012
|
-
return `${minutes} min ${remainingSeconds} sec`;
|
|
7013
|
-
}
|
|
7014
|
-
};
|
|
7015
7075
|
/**
|
|
7016
7076
|
* StreamedContent Component
|
|
7017
7077
|
* Handles real-time streaming of chat messages with a typing-like effect
|
|
@@ -7075,7 +7135,8 @@ const StreamedContent = ({ botData }) => {
|
|
|
7075
7135
|
React.useRef(""); // Tracks the last received message
|
|
7076
7136
|
const thinkingStartTimeRef = React.useRef(null);
|
|
7077
7137
|
const thinkingTimeFinalRef = React.useRef(0);
|
|
7078
|
-
const thinkingHeaderMessageRef = React.useRef("
|
|
7138
|
+
const thinkingHeaderMessageRef = React.useRef("Working for 0m:00s");
|
|
7139
|
+
const streamStartTimeRef = React.useRef(null);
|
|
7079
7140
|
const thinkingDoneRef = React.useRef(false);
|
|
7080
7141
|
const setThinkingContentRef = React.useRef(setThinkingContent); // Store current setThinkingContent function
|
|
7081
7142
|
const streamTimeoutRef = React.useRef(null); // Ref for stream timeout
|
|
@@ -7141,6 +7202,17 @@ const StreamedContent = ({ botData }) => {
|
|
|
7141
7202
|
? botData?.utilityObject?.method
|
|
7142
7203
|
: "PUT";
|
|
7143
7204
|
delete botData.inputBody.chat_input;
|
|
7205
|
+
// Start the timer immediately when the API is called
|
|
7206
|
+
if (!streamStartTimeRef.current) {
|
|
7207
|
+
streamStartTimeRef.current = Date.now();
|
|
7208
|
+
dispatch(smartBotActions.setThinkingContext({
|
|
7209
|
+
streamStartTime: streamStartTimeRef.current,
|
|
7210
|
+
isStreamCompleted: false,
|
|
7211
|
+
finalElapsedSeconds: null,
|
|
7212
|
+
thinkingHeaderMessage: "Working for 0m:00s",
|
|
7213
|
+
thinkingContent: "",
|
|
7214
|
+
}));
|
|
7215
|
+
}
|
|
7144
7216
|
// Initialize SSE connection with API endpoint
|
|
7145
7217
|
sourceRef.current = AxiosSource(endPoint, {
|
|
7146
7218
|
method: method,
|
|
@@ -7229,7 +7301,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
7229
7301
|
setQuestionsStepsMap(lodash.cloneDeep(initialMap));
|
|
7230
7302
|
}
|
|
7231
7303
|
else if (data.status === "thinking") {
|
|
7232
|
-
messageToStoreRef.current.chatData.thinkingResponse.thinkingHeading = "
|
|
7304
|
+
messageToStoreRef.current.chatData.thinkingResponse.thinkingHeading = (jsxRuntime.jsx(ThinkinHeaderInfo, { thinkingHeaderMessage: "Working for 0m:00s" }));
|
|
7233
7305
|
// Start thinking if not already started
|
|
7234
7306
|
if (!isThinking) {
|
|
7235
7307
|
setIsThinking(true);
|
|
@@ -7240,6 +7312,9 @@ const StreamedContent = ({ botData }) => {
|
|
|
7240
7312
|
thinkingContentRef.current = thinkingContentRef.current + data.message;
|
|
7241
7313
|
messageToStoreRef.current.chatData.thinkingResponse.thinkingStream = newValue;
|
|
7242
7314
|
dispatch(smartBotActions.setThinkingContext({
|
|
7315
|
+
streamStartTime: streamStartTimeRef.current,
|
|
7316
|
+
isStreamCompleted: false,
|
|
7317
|
+
finalElapsedSeconds: null,
|
|
7243
7318
|
thinkingHeaderMessage: thinkingHeaderMessageRef.current,
|
|
7244
7319
|
thinkingContent: thinkingContentRef.current,
|
|
7245
7320
|
}));
|
|
@@ -7372,7 +7447,8 @@ const StreamedContent = ({ botData }) => {
|
|
|
7372
7447
|
stepFormStreamControl.baseUrl = _burl;
|
|
7373
7448
|
// If this is the [DONE] chunk, mark streaming as complete
|
|
7374
7449
|
if (data.message === "[DONE]") {
|
|
7375
|
-
|
|
7450
|
+
// Do NOT set stepsDone here — step_form [DONE] is not status:"completed".
|
|
7451
|
+
// stepsDone should only be true when status:"completed" arrives.
|
|
7376
7452
|
setIsStreamingDone(true);
|
|
7377
7453
|
const doneState = streamStateMap.get(streamKey);
|
|
7378
7454
|
if (doneState)
|
|
@@ -7401,10 +7477,13 @@ const StreamedContent = ({ botData }) => {
|
|
|
7401
7477
|
// Store thinking time in messageToStoreRef for persistence
|
|
7402
7478
|
messageToStoreRef.current.chatData.thinkingResponse.thinkingTime = finalThinkingTime;
|
|
7403
7479
|
thinkingTimeFinalRef.current = finalThinkingTime;
|
|
7404
|
-
|
|
7405
|
-
|
|
7480
|
+
// Keep timer running — do NOT set "Worked for" here.
|
|
7481
|
+
// Timer continues showing "Working for Xm:Ys" until status:"completed" arrives.
|
|
7406
7482
|
dispatch(smartBotActions.setThinkingContext({
|
|
7407
|
-
|
|
7483
|
+
streamStartTime: streamStartTimeRef.current,
|
|
7484
|
+
isStreamCompleted: false,
|
|
7485
|
+
finalElapsedSeconds: null,
|
|
7486
|
+
thinkingHeaderMessage: thinkingHeaderMessageRef.current,
|
|
7408
7487
|
thinkingContent: thinkingContentRef.current,
|
|
7409
7488
|
}));
|
|
7410
7489
|
}
|
|
@@ -7518,11 +7597,31 @@ const StreamedContent = ({ botData }) => {
|
|
|
7518
7597
|
if (currentMode === "agent") {
|
|
7519
7598
|
setIsStop(false);
|
|
7520
7599
|
// Use thinkingTime state instead of thinkingTimeFinalRef.current to ensure we have the correct value
|
|
7521
|
-
thinkingTime || thinkingTimeFinalRef.current || 1;
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7600
|
+
const finalThinkingTime = thinkingTime || thinkingTimeFinalRef.current || 1;
|
|
7601
|
+
const completedElapsed = streamStartTimeRef.current
|
|
7602
|
+
? Math.floor((Date.now() - streamStartTimeRef.current) / 1000)
|
|
7603
|
+
: finalThinkingTime;
|
|
7604
|
+
const compMin = Math.floor(completedElapsed / 60);
|
|
7605
|
+
const compSec = completedElapsed % 60;
|
|
7606
|
+
const workedForLabel = `Completed in ${compMin}m:${String(compSec).padStart(2, '0')}s`;
|
|
7607
|
+
// Only stop the timer if we got status:"completed" (stepsDone=true).
|
|
7608
|
+
// If stream ended with step_form [DONE], keep timer running for the next restream.
|
|
7609
|
+
if (stepsDone) {
|
|
7610
|
+
// Completed — use a static string so this chat's heading won't
|
|
7611
|
+
// re-animate when a future chat dispatches a new streamStartTime.
|
|
7612
|
+
messageToStoreRef.current.chatData.thinkingResponse.thinkingHeading = workedForLabel;
|
|
7613
|
+
dispatch(smartBotActions.setThinkingContext({
|
|
7614
|
+
streamStartTime: streamStartTimeRef.current,
|
|
7615
|
+
isStreamCompleted: true,
|
|
7616
|
+
finalElapsedSeconds: completedElapsed,
|
|
7617
|
+
thinkingHeaderMessage: workedForLabel,
|
|
7618
|
+
thinkingContent: thinkingContentRef.current,
|
|
7619
|
+
}));
|
|
7620
|
+
}
|
|
7621
|
+
else {
|
|
7622
|
+
// step_form case: keep heading as the live ThinkinHeaderInfo component so the timer keeps ticking
|
|
7623
|
+
messageToStoreRef.current.chatData.thinkingResponse.thinkingHeading = (jsxRuntime.jsx(ThinkinHeaderInfo, { thinkingHeaderMessage: "Working for 0m:00s" }));
|
|
7624
|
+
}
|
|
7526
7625
|
let actualResponse = lodash.cloneDeep(messageToStoreRef.current.chatData.thinkingResponse.thinkingStream);
|
|
7527
7626
|
messageToStoreRef.current.chatData.thinkingResponse.thinkingContent = actualResponse;
|
|
7528
7627
|
parseResponse(messageToStoreRef.current.chatData, "text");
|
|
@@ -7763,6 +7862,20 @@ const StreamedContent = ({ botData }) => {
|
|
|
7763
7862
|
setShowThoughtDropdown(true);
|
|
7764
7863
|
messageToStoreRef.current.chatData.thinkingResponse.thinkingTime = finalThinkingTime;
|
|
7765
7864
|
}
|
|
7865
|
+
// Stop the timer on abort
|
|
7866
|
+
const abortElapsed = streamStartTimeRef.current
|
|
7867
|
+
? Math.floor((Date.now() - streamStartTimeRef.current) / 1000)
|
|
7868
|
+
: 0;
|
|
7869
|
+
const abortMin = Math.floor(abortElapsed / 60);
|
|
7870
|
+
const abortSec = abortElapsed % 60;
|
|
7871
|
+
const abortLabel = `Completed in ${abortMin}m:${String(abortSec).padStart(2, '0')}s`;
|
|
7872
|
+
dispatch(smartBotActions.setThinkingContext({
|
|
7873
|
+
streamStartTime: streamStartTimeRef.current,
|
|
7874
|
+
isStreamCompleted: true,
|
|
7875
|
+
finalElapsedSeconds: abortElapsed,
|
|
7876
|
+
thinkingHeaderMessage: abortLabel,
|
|
7877
|
+
thinkingContent: thinkingContentRef.current,
|
|
7878
|
+
}));
|
|
7766
7879
|
// If no content yet, show aborted message
|
|
7767
7880
|
// if (isEmpty(messageToStoreRef.current.chatData?.response)) {
|
|
7768
7881
|
messageToStoreRef.current.chatData.response =
|
|
@@ -7811,14 +7924,12 @@ const StreamedContent = ({ botData }) => {
|
|
|
7811
7924
|
};
|
|
7812
7925
|
}, [isStreaming, isStreamingDone]);
|
|
7813
7926
|
/**
|
|
7814
|
-
* Auto-abort previous stream when starting a new one
|
|
7927
|
+
* Auto-abort previous stream when starting a new one.
|
|
7928
|
+
* NOTE: This is intentionally removed. In axios 0.32.0, signal/abort is properly
|
|
7929
|
+
* supported, and this effect was firing on mount causing immediate cancellation.
|
|
7930
|
+
* Stream abort on "new chat" is already handled by handleNewChatClick calling
|
|
7931
|
+
* functionsState.abortStreaming(). The streamStateMap logic handles all other cases.
|
|
7815
7932
|
*/
|
|
7816
|
-
React.useEffect(() => {
|
|
7817
|
-
// If we already have a source and it's streaming, abort it before starting new one
|
|
7818
|
-
if (sourceRef.current && isStreaming) {
|
|
7819
|
-
sourceRef.current.close();
|
|
7820
|
-
}
|
|
7821
|
-
}, [botData.inputBody]); // Trigger when new input is provided
|
|
7822
7933
|
/**
|
|
7823
7934
|
* Set up timeout for auto-abort (optional - can be configured)
|
|
7824
7935
|
*/
|
|
@@ -11650,7 +11761,7 @@ const useConversationManagement = (chatDataRef, currentMode, activeConversationI
|
|
|
11650
11761
|
thinkingStream: item.data,
|
|
11651
11762
|
thinkingContent: item.data,
|
|
11652
11763
|
thinkingTime: 1,
|
|
11653
|
-
thinkingHeading: "
|
|
11764
|
+
thinkingHeading: "Completed in 0m:00s",
|
|
11654
11765
|
};
|
|
11655
11766
|
}
|
|
11656
11767
|
else if (item.chatType === "steps") {
|
|
@@ -11845,7 +11956,9 @@ const useConversationManagement = (chatDataRef, currentMode, activeConversationI
|
|
|
11845
11956
|
thinkingResponse: msg.thinkingResponse ? {
|
|
11846
11957
|
thinkingStream: msg.thinkingResponse.thinkingStream,
|
|
11847
11958
|
thinkingTime: msg.thinkingResponse.thinkingTime,
|
|
11848
|
-
thinkingHeading: msg.thinkingResponse.thinkingHeading
|
|
11959
|
+
thinkingHeading: typeof msg.thinkingResponse.thinkingHeading === 'string'
|
|
11960
|
+
? msg.thinkingResponse.thinkingHeading
|
|
11961
|
+
: "Completed in 0m:00s",
|
|
11849
11962
|
} : undefined,
|
|
11850
11963
|
}
|
|
11851
11964
|
}))
|
|
@@ -12510,10 +12623,14 @@ const SmartBot = (props) => {
|
|
|
12510
12623
|
message.isFormDisabled = index !== lastBotMessageIndex;
|
|
12511
12624
|
message.messageIndex = index;
|
|
12512
12625
|
let originalUtilityObject = message.utilityObject;
|
|
12626
|
+
let originalThinkingResponse = message.thinkingResponse;
|
|
12513
12627
|
let newMessage = lodash.cloneDeep(message);
|
|
12514
12628
|
if (originalUtilityObject) {
|
|
12515
12629
|
newMessage.utilityObject = originalUtilityObject;
|
|
12516
12630
|
}
|
|
12631
|
+
if (originalThinkingResponse) {
|
|
12632
|
+
newMessage.thinkingResponse = originalThinkingResponse;
|
|
12633
|
+
}
|
|
12517
12634
|
message.jsx = (jsxRuntime.jsx(BotMessage, { botData: newMessage, state: loadingState, handleLikeDislike: handleLikeDislike, props: properties }));
|
|
12518
12635
|
let actualProps = {
|
|
12519
12636
|
botData: newMessage,
|
|
@@ -12528,6 +12645,15 @@ const SmartBot = (props) => {
|
|
|
12528
12645
|
});
|
|
12529
12646
|
// Create a deep clone and remove JSX properties to avoid circular references
|
|
12530
12647
|
let newChat = lodash.cloneDeep(chatDataInfoRef?.current[currentMode]);
|
|
12648
|
+
// Restore thinkingResponse (may contain JSX components like ThinkinHeaderInfo)
|
|
12649
|
+
// which cloneDeep serializes into plain objects
|
|
12650
|
+
const originalMessages = chatDataInfoRef?.current[currentMode]?.conversations?.[activeConversationId]?.messages || [];
|
|
12651
|
+
const clonedMessages = newChat?.conversations?.[activeConversationId]?.messages || [];
|
|
12652
|
+
originalMessages.forEach((origMsg, idx) => {
|
|
12653
|
+
if (origMsg.thinkingResponse && clonedMessages[idx]) {
|
|
12654
|
+
clonedMessages[idx].thinkingResponse = origMsg.thinkingResponse;
|
|
12655
|
+
}
|
|
12656
|
+
});
|
|
12531
12657
|
setConversation(newChat);
|
|
12532
12658
|
}
|
|
12533
12659
|
else if (showModal) {
|
|
@@ -12621,7 +12747,10 @@ const SmartBot = (props) => {
|
|
|
12621
12747
|
// if(!isEmpty(userInput)) {
|
|
12622
12748
|
dispatch(smartBotActions.setThinkingContext({
|
|
12623
12749
|
thinkingContent: "",
|
|
12624
|
-
thinkingHeaderMessage: "
|
|
12750
|
+
thinkingHeaderMessage: "Working for 0m:00s",
|
|
12751
|
+
streamStartTime: Date.now(),
|
|
12752
|
+
isStreamCompleted: false,
|
|
12753
|
+
finalElapsedSeconds: null,
|
|
12625
12754
|
}));
|
|
12626
12755
|
// }
|
|
12627
12756
|
prepareDataAndSendToAgent(data, true, {
|
|
@@ -12836,7 +12965,10 @@ const SmartBot = (props) => {
|
|
|
12836
12965
|
setShowChatPlaceholder(true);
|
|
12837
12966
|
dispatch(smartBotActions.setThinkingContext({
|
|
12838
12967
|
thinkingContent: "",
|
|
12839
|
-
thinkingHeaderMessage: "
|
|
12968
|
+
thinkingHeaderMessage: "Working for 0m:00s",
|
|
12969
|
+
streamStartTime: null,
|
|
12970
|
+
isStreamCompleted: false,
|
|
12971
|
+
finalElapsedSeconds: null,
|
|
12840
12972
|
}));
|
|
12841
12973
|
setInitValue(true);
|
|
12842
12974
|
setSessionId("");
|