@ai-group/chat-sdk 3.5.0 → 3.5.1
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/cjs/components/XAdkChatbot/index.js +21 -3
- package/dist/cjs/components/XAdkChatbot/index.js.map +2 -2
- package/dist/cjs/hooks/useADKChat.js +156 -12
- package/dist/cjs/hooks/useADKChat.js.map +3 -3
- package/dist/esm/components/XAdkChatbot/index.js +29 -5
- package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
- package/dist/esm/hooks/useADKChat.js +199 -41
- package/dist/esm/hooks/useADKChat.js.map +1 -1
- package/dist/umd/chat-sdk.min.js +1 -1
- package/package.json +1 -1
|
@@ -44,6 +44,9 @@ var combineTextParts = function combineTextParts(parts) {
|
|
|
44
44
|
}
|
|
45
45
|
return result;
|
|
46
46
|
};
|
|
47
|
+
|
|
48
|
+
// 后台会话连接状态
|
|
49
|
+
|
|
47
50
|
function useADKChat(_ref) {
|
|
48
51
|
var _ref$url = _ref.url,
|
|
49
52
|
url = _ref$url === void 0 ? window.location.origin : _ref$url,
|
|
@@ -119,6 +122,13 @@ function useADKChat(_ref) {
|
|
|
119
122
|
setMessages = _useState20[1];
|
|
120
123
|
// 用户自定义业务参数 (stateDelta),每次发送请求时携带
|
|
121
124
|
var stateDeltaRef = useRef(undefined);
|
|
125
|
+
|
|
126
|
+
// ===== 多会话后台连接管理 =====
|
|
127
|
+
var backgroundRef = useRef(new Map());
|
|
128
|
+
var messagesRef = useRef(messages);
|
|
129
|
+
messagesRef.current = messages;
|
|
130
|
+
var currentSessionIdRef = useRef(currentSessionId);
|
|
131
|
+
currentSessionIdRef.current = currentSessionId;
|
|
122
132
|
var mergedMessages = useMemo(function () {
|
|
123
133
|
var fnResMap = {};
|
|
124
134
|
messages.forEach(function (msg) {
|
|
@@ -366,15 +376,24 @@ function useADKChat(_ref) {
|
|
|
366
376
|
// 发送消息请求
|
|
367
377
|
var sendMessageRequest = useCallback(function (values) {
|
|
368
378
|
return new Promise(function (resolve) {
|
|
369
|
-
|
|
379
|
+
var targetSessionId = values.sessionId || currentSessionIdRef.current;
|
|
380
|
+
|
|
381
|
+
// 只 abort 同一 session 的旧连接
|
|
382
|
+
if (targetSessionId === currentSessionIdRef.current && ctrl.current) {
|
|
370
383
|
ctrl.current.abort();
|
|
371
384
|
}
|
|
372
|
-
|
|
373
|
-
|
|
385
|
+
var newCtrl = new AbortController();
|
|
386
|
+
if (targetSessionId === currentSessionIdRef.current) {
|
|
387
|
+
setLoading(true);
|
|
388
|
+
ctrl.current = newCtrl;
|
|
389
|
+
}
|
|
374
390
|
var requestUrl = "".concat(url, "/api/gateway-web/openApi/v1/aizt/app/").concat(appNo, "/sendMsgStreaming");
|
|
391
|
+
|
|
392
|
+
// 后台流式文本拼接
|
|
393
|
+
var bgTextMsg = null;
|
|
375
394
|
fetchEventSource(requestUrl, {
|
|
376
395
|
method: "POST",
|
|
377
|
-
signal:
|
|
396
|
+
signal: newCtrl.signal,
|
|
378
397
|
body: JSON.stringify(values),
|
|
379
398
|
openWhenHidden: true,
|
|
380
399
|
headers: {
|
|
@@ -418,7 +437,6 @@ function useADKChat(_ref) {
|
|
|
418
437
|
// 转换为旧格式
|
|
419
438
|
chunkJson = _objectSpread(_objectSpread({}, rawData.data), {}, {
|
|
420
439
|
content: rawData.data,
|
|
421
|
-
// data 本身就是 content
|
|
422
440
|
invocationId: rawData.result.invocationId,
|
|
423
441
|
sessionId: rawData.result.sessionId,
|
|
424
442
|
id: rawData.result.invocationId
|
|
@@ -428,6 +446,84 @@ function useADKChat(_ref) {
|
|
|
428
446
|
message.warning(chunkJson.error);
|
|
429
447
|
return;
|
|
430
448
|
}
|
|
449
|
+
|
|
450
|
+
// 判断是否为后台 session
|
|
451
|
+
var isBackground = currentSessionIdRef.current !== targetSessionId;
|
|
452
|
+
if (isBackground) {
|
|
453
|
+
// 后台 session:更新 backgroundRef 中的消息
|
|
454
|
+
var bg = backgroundRef.current.get(targetSessionId);
|
|
455
|
+
if (!bg) return;
|
|
456
|
+
if (chunkJson.content) {
|
|
457
|
+
if (chunkJson.content.role === "followup") return;
|
|
458
|
+
var _iterator2 = _createForOfIteratorHelper(combineTextParts(chunkJson.content.parts)),
|
|
459
|
+
_step2;
|
|
460
|
+
try {
|
|
461
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
462
|
+
var part = _step2.value;
|
|
463
|
+
var isPureText = part.text && !part.fileData;
|
|
464
|
+
if (isPureText) {
|
|
465
|
+
var _chunkJson, _bgTextMsg;
|
|
466
|
+
if (((_chunkJson = chunkJson) === null || _chunkJson === void 0 ? void 0 : _chunkJson.partial) === false) continue;
|
|
467
|
+
var newChunk = part.text || "";
|
|
468
|
+
if (!bgTextMsg || ((_bgTextMsg = bgTextMsg) === null || _bgTextMsg === void 0 ? void 0 : _bgTextMsg.thought) !== part.thought) {
|
|
469
|
+
var newMessage = {
|
|
470
|
+
id: v4(),
|
|
471
|
+
author: chunkJson.author,
|
|
472
|
+
invocationId: chunkJson.invocationId,
|
|
473
|
+
eventId: chunkJson.id,
|
|
474
|
+
timestamp: chunkJson.timestamp,
|
|
475
|
+
role: "bot",
|
|
476
|
+
text: newChunk,
|
|
477
|
+
thought: part.thought
|
|
478
|
+
};
|
|
479
|
+
bgTextMsg = newMessage;
|
|
480
|
+
bg.messages = [].concat(_toConsumableArray(bg.messages), [newMessage]);
|
|
481
|
+
} else {
|
|
482
|
+
bgTextMsg = _objectSpread(_objectSpread({}, bgTextMsg), {}, {
|
|
483
|
+
text: (bgTextMsg.text || "") + newChunk
|
|
484
|
+
});
|
|
485
|
+
bg.messages = bg.messages.map(function (m) {
|
|
486
|
+
return m.id === bgTextMsg.id ? bgTextMsg : m;
|
|
487
|
+
});
|
|
488
|
+
if (chunkJson.finishReason === "stop") {
|
|
489
|
+
bgTextMsg = null;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
} else {
|
|
493
|
+
bgTextMsg = null;
|
|
494
|
+
var msg = {
|
|
495
|
+
id: v4(),
|
|
496
|
+
author: chunkJson.author,
|
|
497
|
+
invocationId: chunkJson.invocationId,
|
|
498
|
+
eventId: chunkJson.id,
|
|
499
|
+
timestamp: chunkJson.timestamp,
|
|
500
|
+
role: "bot"
|
|
501
|
+
};
|
|
502
|
+
if (part.functionCall) msg.functionCall = part.functionCall;else if (part.functionResponse) msg.functionResponse = part.functionResponse;else if (part.executableCode) msg.executableCode = part.executableCode;else if (part.codeExecutionResult) msg.codeExecutionResult = part.codeExecutionResult;else {
|
|
503
|
+
msg.text = part.text;
|
|
504
|
+
msg.thought = part.thought;
|
|
505
|
+
if (part.fileData) msg.fileData = [part.fileData];
|
|
506
|
+
}
|
|
507
|
+
bg.messages = [].concat(_toConsumableArray(bg.messages), [msg]);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
} catch (err) {
|
|
511
|
+
_iterator2.e(err);
|
|
512
|
+
} finally {
|
|
513
|
+
_iterator2.f();
|
|
514
|
+
}
|
|
515
|
+
} else if (chunkJson.errorMessage) {
|
|
516
|
+
bg.messages = [].concat(_toConsumableArray(bg.messages), [{
|
|
517
|
+
id: v4(),
|
|
518
|
+
text: chunkJson.errorMessage,
|
|
519
|
+
role: "bot"
|
|
520
|
+
}]);
|
|
521
|
+
}
|
|
522
|
+
bg.textMsgRef = bgTextMsg;
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// 前台 session:正常处理
|
|
431
527
|
onStream === null || onStream === void 0 || onStream(chunkJson);
|
|
432
528
|
updateLastBotEventMeta(chunkJson);
|
|
433
529
|
if (chunkJson.content) {
|
|
@@ -437,19 +533,19 @@ function useADKChat(_ref) {
|
|
|
437
533
|
return;
|
|
438
534
|
}
|
|
439
535
|
// eslint-disable-next-line no-restricted-syntax
|
|
440
|
-
var
|
|
441
|
-
|
|
536
|
+
var _iterator3 = _createForOfIteratorHelper(combineTextParts(chunkJson.content.parts)),
|
|
537
|
+
_step3;
|
|
442
538
|
try {
|
|
443
|
-
for (
|
|
444
|
-
var
|
|
445
|
-
var
|
|
539
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
540
|
+
var _chunkJson2;
|
|
541
|
+
var _part = _step3.value;
|
|
446
542
|
// partial为 true 时忽略该条消息文本
|
|
447
|
-
processPart(chunkJson,
|
|
543
|
+
processPart(chunkJson, _part, ((_chunkJson2 = chunkJson) === null || _chunkJson2 === void 0 ? void 0 : _chunkJson2.partial) === false);
|
|
448
544
|
}
|
|
449
545
|
} catch (err) {
|
|
450
|
-
|
|
546
|
+
_iterator3.e(err);
|
|
451
547
|
} finally {
|
|
452
|
-
|
|
548
|
+
_iterator3.f();
|
|
453
549
|
}
|
|
454
550
|
} else if (chunkJson.errorMessage) {
|
|
455
551
|
processErrorMessage(chunkJson);
|
|
@@ -458,16 +554,31 @@ function useADKChat(_ref) {
|
|
|
458
554
|
}
|
|
459
555
|
},
|
|
460
556
|
onclose: function onclose() {
|
|
461
|
-
|
|
462
|
-
if (
|
|
463
|
-
var
|
|
464
|
-
|
|
557
|
+
var isBackground = currentSessionIdRef.current !== targetSessionId;
|
|
558
|
+
if (isBackground) {
|
|
559
|
+
var bg = backgroundRef.current.get(targetSessionId);
|
|
560
|
+
if (bg) {
|
|
561
|
+
bg.loading = false;
|
|
562
|
+
bg.textMsgRef = null;
|
|
563
|
+
}
|
|
564
|
+
} else {
|
|
565
|
+
setLoading(false);
|
|
566
|
+
if (textMsgRef.current) {
|
|
567
|
+
var _textMsgRef$current;
|
|
568
|
+
onMessage === null || onMessage === void 0 || onMessage(((_textMsgRef$current = textMsgRef.current) === null || _textMsgRef$current === void 0 ? void 0 : _textMsgRef$current.text) || "", textMsgRef.current);
|
|
569
|
+
}
|
|
570
|
+
textMsgRef.current = null;
|
|
465
571
|
}
|
|
466
|
-
textMsgRef.current = null;
|
|
467
572
|
resolve();
|
|
468
573
|
},
|
|
469
574
|
onerror: function onerror(error) {
|
|
470
|
-
|
|
575
|
+
var isBackground = currentSessionIdRef.current !== targetSessionId;
|
|
576
|
+
if (isBackground) {
|
|
577
|
+
var bg = backgroundRef.current.get(targetSessionId);
|
|
578
|
+
if (bg) bg.loading = false;
|
|
579
|
+
} else {
|
|
580
|
+
setLoading(false);
|
|
581
|
+
}
|
|
471
582
|
resolve();
|
|
472
583
|
console.error("EventSource failed:", error);
|
|
473
584
|
throw error;
|
|
@@ -678,13 +789,14 @@ function useADKChat(_ref) {
|
|
|
678
789
|
});
|
|
679
790
|
};
|
|
680
791
|
|
|
681
|
-
//
|
|
792
|
+
// 停止会话(只中断前台连接)
|
|
682
793
|
var stopChat = useCallback(function () {
|
|
683
794
|
var _ctrl$current;
|
|
684
795
|
(_ctrl$current = ctrl.current) === null || _ctrl$current === void 0 || _ctrl$current.abort();
|
|
796
|
+
ctrl.current = null;
|
|
685
797
|
setLoading(false);
|
|
686
798
|
textMsgRef.current = null;
|
|
687
|
-
}, [
|
|
799
|
+
}, []);
|
|
688
800
|
|
|
689
801
|
// 清除/重置会话
|
|
690
802
|
var clearChat = function clearChat() {
|
|
@@ -737,11 +849,11 @@ function useADKChat(_ref) {
|
|
|
737
849
|
finishReason: item.finishReason,
|
|
738
850
|
raw: item
|
|
739
851
|
};
|
|
740
|
-
var
|
|
741
|
-
|
|
852
|
+
var _iterator4 = _createForOfIteratorHelper(textParts),
|
|
853
|
+
_step4;
|
|
742
854
|
try {
|
|
743
|
-
for (
|
|
744
|
-
var part =
|
|
855
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
856
|
+
var part = _step4.value;
|
|
745
857
|
if (part.inlineData) {
|
|
746
858
|
msg.inlineData = {
|
|
747
859
|
displayName: part.inlineData.displayName,
|
|
@@ -758,9 +870,9 @@ function useADKChat(_ref) {
|
|
|
758
870
|
}
|
|
759
871
|
}
|
|
760
872
|
} catch (err) {
|
|
761
|
-
|
|
873
|
+
_iterator4.e(err);
|
|
762
874
|
} finally {
|
|
763
|
-
|
|
875
|
+
_iterator4.f();
|
|
764
876
|
}
|
|
765
877
|
if (fileDataParts.length > 0) {
|
|
766
878
|
msg.fileData = fileDataParts.map(function (part) {
|
|
@@ -815,12 +927,12 @@ function useADKChat(_ref) {
|
|
|
815
927
|
// 设置当前会话详情
|
|
816
928
|
var setCurrentSession = /*#__PURE__*/function () {
|
|
817
929
|
var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(sessionId) {
|
|
818
|
-
var _yield$fetchSessionDe, data, result, _appInfo$onboardingIn3, _appInfo$onboardingIn4;
|
|
930
|
+
var prevSessionId, bg, _yield$fetchSessionDe, data, result, _appInfo$onboardingIn3, _appInfo$onboardingIn4;
|
|
819
931
|
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
820
932
|
while (1) switch (_context4.prev = _context4.next) {
|
|
821
933
|
case 0:
|
|
822
934
|
if (!sessionId) {
|
|
823
|
-
_context4.next =
|
|
935
|
+
_context4.next = 26;
|
|
824
936
|
break;
|
|
825
937
|
}
|
|
826
938
|
if (!(sessionId === currentSessionId)) {
|
|
@@ -829,39 +941,72 @@ function useADKChat(_ref) {
|
|
|
829
941
|
}
|
|
830
942
|
return _context4.abrupt("return");
|
|
831
943
|
case 3:
|
|
832
|
-
//
|
|
833
|
-
|
|
834
|
-
|
|
944
|
+
// 1. 将当前会话挂起到后台(不中断 SSE 连接)
|
|
945
|
+
prevSessionId = currentSessionId;
|
|
946
|
+
if (ctrl.current) {
|
|
947
|
+
// 有活跃流式连接,保存到后台
|
|
948
|
+
backgroundRef.current.set(prevSessionId, {
|
|
949
|
+
ctrl: ctrl.current,
|
|
950
|
+
messages: _toConsumableArray(messagesRef.current),
|
|
951
|
+
loading: true,
|
|
952
|
+
textMsgRef: textMsgRef.current
|
|
953
|
+
});
|
|
954
|
+
ctrl.current = null;
|
|
955
|
+
textMsgRef.current = null;
|
|
956
|
+
setLoading(false);
|
|
957
|
+
} else if (messagesRef.current.length > 0) {
|
|
958
|
+
// 无活跃连接但有消息,缓存用于切回
|
|
959
|
+
backgroundRef.current.set(prevSessionId, {
|
|
960
|
+
ctrl: new AbortController(),
|
|
961
|
+
messages: _toConsumableArray(messagesRef.current),
|
|
962
|
+
loading: false,
|
|
963
|
+
textMsgRef: null
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// 2. 尝试从后台恢复目标会话
|
|
968
|
+
bg = backgroundRef.current.get(sessionId);
|
|
969
|
+
if (!bg) {
|
|
970
|
+
_context4.next = 15;
|
|
971
|
+
break;
|
|
972
|
+
}
|
|
973
|
+
setMessages(bg.messages);
|
|
974
|
+
setLoading(bg.loading);
|
|
975
|
+
textMsgRef.current = bg.textMsgRef;
|
|
976
|
+
ctrl.current = bg.loading ? bg.ctrl : null;
|
|
977
|
+
setCurrentSessionId(sessionId);
|
|
978
|
+
setInitialized(true);
|
|
979
|
+
backgroundRef.current.delete(sessionId);
|
|
980
|
+
return _context4.abrupt("return");
|
|
981
|
+
case 15:
|
|
982
|
+
// 3. 后台没有目标 session,走 API 加载(原有逻辑)
|
|
835
983
|
setInitialized(false);
|
|
836
|
-
setCurrentSessionId(sessionId);
|
|
837
|
-
_context4.next =
|
|
984
|
+
setCurrentSessionId(sessionId);
|
|
985
|
+
_context4.next = 19;
|
|
838
986
|
return fetchSessionDetail({
|
|
839
987
|
url: url,
|
|
840
988
|
appNo: appNo,
|
|
841
989
|
sessionId: sessionId,
|
|
842
990
|
token: token
|
|
843
991
|
});
|
|
844
|
-
case
|
|
992
|
+
case 19:
|
|
845
993
|
_yield$fetchSessionDe = _context4.sent;
|
|
846
994
|
data = _yield$fetchSessionDe.data;
|
|
847
995
|
result = _yield$fetchSessionDe.result;
|
|
848
996
|
if ((result === null || result === void 0 ? void 0 : result.code) === API_SUCCESS_CODE) {
|
|
849
997
|
setPrologue((appInfo === null || appInfo === void 0 || (_appInfo$onboardingIn3 = appInfo.onboardingInfo) === null || _appInfo$onboardingIn3 === void 0 ? void 0 : _appInfo$onboardingIn3.prologue) || "");
|
|
850
|
-
// 新接口直接返回按 event/item 结构的数组,传入 formatMessages 处理
|
|
851
998
|
if (Array.isArray(data) && data.length > 0) {
|
|
852
999
|
formatMessages(data, true);
|
|
853
1000
|
} else {
|
|
854
1001
|
setSuggestedQuestions((appInfo === null || appInfo === void 0 || (_appInfo$onboardingIn4 = appInfo.onboardingInfo) === null || _appInfo$onboardingIn4 === void 0 ? void 0 : _appInfo$onboardingIn4.suggested_questions) || []);
|
|
855
1002
|
}
|
|
856
1003
|
}
|
|
857
|
-
// 恢复 initialized,触发 XAdkChatbot 的初始化置底逻辑
|
|
858
1004
|
setInitialized(true);
|
|
859
|
-
_context4.next =
|
|
1005
|
+
_context4.next = 27;
|
|
860
1006
|
break;
|
|
861
|
-
case
|
|
862
|
-
// 兼容 无 session异常
|
|
1007
|
+
case 26:
|
|
863
1008
|
setCurrentSessionId(v4());
|
|
864
|
-
case
|
|
1009
|
+
case 27:
|
|
865
1010
|
case "end":
|
|
866
1011
|
return _context4.stop();
|
|
867
1012
|
}
|
|
@@ -1179,6 +1324,19 @@ function useADKChat(_ref) {
|
|
|
1179
1324
|
initAppConversations(true);
|
|
1180
1325
|
}
|
|
1181
1326
|
}, [appInfo]);
|
|
1327
|
+
|
|
1328
|
+
// 组件卸载时清理所有连接(前台 + 后台)
|
|
1329
|
+
useEffect(function () {
|
|
1330
|
+
return function () {
|
|
1331
|
+
var _ctrl$current2;
|
|
1332
|
+
(_ctrl$current2 = ctrl.current) === null || _ctrl$current2 === void 0 || _ctrl$current2.abort();
|
|
1333
|
+
backgroundRef.current.forEach(function (bg) {
|
|
1334
|
+
var _bg$ctrl;
|
|
1335
|
+
return (_bg$ctrl = bg.ctrl) === null || _bg$ctrl === void 0 ? void 0 : _bg$ctrl.abort();
|
|
1336
|
+
});
|
|
1337
|
+
backgroundRef.current.clear();
|
|
1338
|
+
};
|
|
1339
|
+
}, []);
|
|
1182
1340
|
return {
|
|
1183
1341
|
appInfo: appInfo,
|
|
1184
1342
|
startChat: startChat,
|