@ai-group/chat-sdk 3.6.2 → 3.6.4

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.
Files changed (44) hide show
  1. package/dist/cjs/components/FileGallery/index.d.ts +0 -30
  2. package/dist/cjs/components/FileGallery/index.js +287 -209
  3. package/dist/cjs/components/FileGallery/index.js.map +2 -2
  4. package/dist/cjs/components/FileGallery/styles.d.ts +5 -0
  5. package/dist/cjs/components/FileGallery/styles.js +106 -0
  6. package/dist/cjs/components/FileGallery/styles.js.map +2 -2
  7. package/dist/cjs/components/XAdkProvider/compound/Sender.js +3 -2
  8. package/dist/cjs/components/XAdkProvider/compound/Sender.js.map +2 -2
  9. package/dist/cjs/components/XAdkSender/index.js +1 -0
  10. package/dist/cjs/components/XAdkSender/index.js.map +2 -2
  11. package/dist/cjs/hooks/useADKChat.js +365 -167
  12. package/dist/cjs/hooks/useADKChat.js.map +3 -3
  13. package/dist/cjs/hooks/useAgentGenerator.js +4 -3
  14. package/dist/cjs/hooks/useAgentGenerator.js.map +2 -2
  15. package/dist/cjs/types/FileGallery.d.ts +41 -0
  16. package/dist/cjs/types/FileGallery.js.map +1 -1
  17. package/dist/cjs/types/XAdkProvider.d.ts +4 -0
  18. package/dist/cjs/types/XAdkProvider.js.map +1 -1
  19. package/dist/cjs/types/XAiProvider.d.ts +13 -46
  20. package/dist/cjs/types/XAiProvider.js +2 -25
  21. package/dist/cjs/types/XAiProvider.js.map +3 -3
  22. package/dist/esm/components/FileGallery/index.d.ts +0 -30
  23. package/dist/esm/components/FileGallery/index.js +362 -364
  24. package/dist/esm/components/FileGallery/index.js.map +1 -1
  25. package/dist/esm/components/FileGallery/styles.d.ts +5 -0
  26. package/dist/esm/components/FileGallery/styles.js +10 -2
  27. package/dist/esm/components/FileGallery/styles.js.map +1 -1
  28. package/dist/esm/components/XAdkProvider/compound/Sender.js +5 -3
  29. package/dist/esm/components/XAdkProvider/compound/Sender.js.map +1 -1
  30. package/dist/esm/components/XAdkSender/index.js +1 -0
  31. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  32. package/dist/esm/hooks/useADKChat.js +314 -133
  33. package/dist/esm/hooks/useADKChat.js.map +1 -1
  34. package/dist/esm/hooks/useAgentGenerator.js +4 -3
  35. package/dist/esm/hooks/useAgentGenerator.js.map +1 -1
  36. package/dist/esm/types/FileGallery.d.ts +41 -0
  37. package/dist/esm/types/FileGallery.js.map +1 -1
  38. package/dist/esm/types/XAdkProvider.d.ts +4 -0
  39. package/dist/esm/types/XAdkProvider.js.map +1 -1
  40. package/dist/esm/types/XAiProvider.d.ts +13 -46
  41. package/dist/esm/types/XAiProvider.js +7 -39
  42. package/dist/esm/types/XAiProvider.js.map +1 -1
  43. package/dist/umd/chat-sdk.min.js +1 -1
  44. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
2
2
  import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
- import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
4
3
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
4
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
5
5
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
6
6
  import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
7
7
  import { useEffect, useCallback, useMemo, useRef, useState } from "react";
@@ -44,10 +44,150 @@ var combineTextParts = function combineTextParts(parts) {
44
44
  }
45
45
  return result;
46
46
  };
47
+ var DEFAULT_SESSION_EVENTS_POLLING_INTERVAL = 10000;
48
+ var getMessageEventId = function getMessageEventId(messageItem) {
49
+ var _messageItem$raw;
50
+ return messageItem.eventId || ((_messageItem$raw = messageItem.raw) === null || _messageItem$raw === void 0 ? void 0 : _messageItem$raw.id);
51
+ };
52
+ var mapSessionMessages = function mapSessionMessages(sessionEvents) {
53
+ var mapped = [];
54
+ sessionEvents.forEach(function (item) {
55
+ if (!item || !item.content || !Array.isArray(item.content.parts)) return;
56
+ // 后端为异步任务插入的用户事件仅用于关联任务,不在页面展示。
57
+ if (item.author === "user" && item.content.parts.some(function (part) {
58
+ return part.task;
59
+ })) return;
60
+ var role = (item.content.role || "").toLowerCase() === "user" ? "user" : "bot";
61
+ var parts = item.content.parts.filter(function (part) {
62
+ if (!part) return false;
63
+ return Boolean(part.text || part.inlineData || part.functionCall || part.functionResponse || part.fileData || part.executableCode || part.codeExecutionResult || part.errorMessage);
64
+ });
65
+ if (parts.length === 0) return;
66
+ var textParts = parts.filter(function (part) {
67
+ return part.text || part.errorMessage || part.inlineData;
68
+ });
69
+ var fileDataParts = parts.filter(function (part) {
70
+ return part.fileData;
71
+ });
72
+ var otherParts = parts.filter(function (part) {
73
+ return !part.text && !part.errorMessage && !part.inlineData && !part.fileData;
74
+ });
75
+ if (textParts.length > 0 || fileDataParts.length > 0) {
76
+ var messageItem = {
77
+ id: v4(),
78
+ author: item.author,
79
+ invocationId: item.invocationId,
80
+ eventId: item.id,
81
+ timestamp: item.timestamp,
82
+ isLike: item.isLike,
83
+ role: role,
84
+ modelCode: item.modelCode,
85
+ usageMetadata: item.usageMetadata,
86
+ finishReason: item.finishReason,
87
+ raw: item
88
+ };
89
+ textParts.forEach(function (part) {
90
+ if (part.inlineData) {
91
+ messageItem.inlineData = {
92
+ displayName: part.inlineData.displayName,
93
+ data: part.inlineData.data,
94
+ mimeType: part.inlineData.mimeType
95
+ };
96
+ }
97
+ if (part.text) {
98
+ messageItem.text = (messageItem.text ? "".concat(messageItem.text, "\n") : "") + part.text;
99
+ if (typeof part.thought !== "undefined") messageItem.thought = part.thought;
100
+ }
101
+ if (part.errorMessage) {
102
+ messageItem.text = (messageItem.text ? "".concat(messageItem.text, "\n") : "") + part.errorMessage;
103
+ }
104
+ });
105
+ if (fileDataParts.length > 0) {
106
+ messageItem.fileData = fileDataParts.map(function (part) {
107
+ return {
108
+ displayName: part.fileData.displayName || "",
109
+ fileUri: part.fileData.fileUri,
110
+ mimeType: part.fileData.mimeType
111
+ };
112
+ });
113
+ }
114
+ mapped.push(messageItem);
115
+ }
116
+ otherParts.forEach(function (part) {
117
+ var messageItem = {
118
+ id: v4(),
119
+ author: item.author,
120
+ invocationId: item.invocationId,
121
+ eventId: item.id,
122
+ timestamp: item.timestamp,
123
+ isLike: item.isLike,
124
+ role: role,
125
+ modelCode: item.modelCode,
126
+ usageMetadata: item.usageMetadata,
127
+ finishReason: item.finishReason,
128
+ raw: item
129
+ };
130
+ if (part.functionCall) messageItem.functionCall = part.functionCall;
131
+ if (part.executableCode) messageItem.executableCode = part.executableCode;
132
+ if (part.codeExecutionResult) messageItem.codeExecutionResult = part.codeExecutionResult;
133
+ if (part.functionResponse) {
134
+ var functionCallMessage = mapped.find(function (currentMessage) {
135
+ var _currentMessage$funct, _part$functionRespons;
136
+ return ((_currentMessage$funct = currentMessage.functionCall) === null || _currentMessage$funct === void 0 ? void 0 : _currentMessage$funct.id) === ((_part$functionRespons = part.functionResponse) === null || _part$functionRespons === void 0 ? void 0 : _part$functionRespons.id);
137
+ });
138
+ if (functionCallMessage) {
139
+ functionCallMessage.functionResponse = part.functionResponse;
140
+ }
141
+ return;
142
+ }
143
+ mapped.push(messageItem);
144
+ });
145
+ });
146
+ return mapped;
147
+ };
148
+ var insertMissingSessionEvents = function insertMissingSessionEvents(currentMessages, sessionEvents) {
149
+ var renderedEventIds = new Set(currentMessages.map(getMessageEventId).filter(Boolean));
150
+ var missingEvents = sessionEvents.filter(function (event) {
151
+ var _event$content, _event$content2;
152
+ var parts = (_event$content = event.content) === null || _event$content === void 0 ? void 0 : _event$content.parts;
153
+ return Boolean(event.id) && ((_event$content2 = event.content) === null || _event$content2 === void 0 ? void 0 : _event$content2.role) === "model" && Array.isArray(parts) && parts.length > 0 && !renderedEventIds.has(event.id);
154
+ });
155
+ if (missingEvents.length === 0) return currentMessages;
156
+ var missingMessages = mapSessionMessages(missingEvents);
157
+ if (missingMessages.length === 0) return currentMessages;
158
+ var eventOrder = new Map(sessionEvents.map(function (event, index) {
159
+ return [event.id, index];
160
+ }));
161
+ var getMessageOrder = function getMessageOrder(messageItem) {
162
+ var _messageItem$timestam, _messageItem$raw2;
163
+ var eventId = getMessageEventId(messageItem);
164
+ if (eventId && eventOrder.has(eventId)) return eventOrder.get(eventId);
165
+ var timestamp = (_messageItem$timestam = messageItem.timestamp) !== null && _messageItem$timestam !== void 0 ? _messageItem$timestam : (_messageItem$raw2 = messageItem.raw) === null || _messageItem$raw2 === void 0 ? void 0 : _messageItem$raw2.timestamp;
166
+ if (timestamp !== undefined) {
167
+ var nextEventIndex = sessionEvents.findIndex(function (event) {
168
+ return (event.timestamp || 0) > timestamp;
169
+ });
170
+ return nextEventIndex < 0 ? sessionEvents.length + 0.5 : nextEventIndex - 0.5;
171
+ }
172
+ return Number.POSITIVE_INFINITY;
173
+ };
174
+ var nextMessages = _toConsumableArray(currentMessages);
175
+ missingMessages.forEach(function (messageItem) {
176
+ var targetOrder = getMessageOrder(messageItem);
177
+ var insertIndex = nextMessages.findIndex(function (currentMessage) {
178
+ var currentOrder = getMessageOrder(currentMessage);
179
+ return Number.isFinite(currentOrder) && currentOrder > targetOrder;
180
+ });
181
+ if (insertIndex < 0) insertIndex = nextMessages.length;
182
+ nextMessages.splice(insertIndex, 0, messageItem);
183
+ });
184
+ return nextMessages;
185
+ };
47
186
 
48
187
  // 后台会话连接状态
49
188
 
50
189
  function useADKChat(_ref) {
190
+ var _config$session$pollS, _config$session, _config$session$sessi, _config$session2;
51
191
  var _ref$url = _ref.url,
52
192
  url = _ref$url === void 0 ? window.location.origin : _ref$url,
53
193
  token = _ref.token,
@@ -65,7 +205,12 @@ function useADKChat(_ref) {
65
205
  var _useState = useState(false),
66
206
  _useState2 = _slicedToArray(_useState, 2),
67
207
  loading = _useState2[0],
68
- setLoading = _useState2[1];
208
+ setLoadingState = _useState2[1];
209
+ var loadingRef = useRef(false);
210
+ var setLoading = useCallback(function (nextLoading) {
211
+ loadingRef.current = nextLoading;
212
+ setLoadingState(nextLoading);
213
+ }, []);
69
214
  var _useState3 = useState(false),
70
215
  _useState4 = _slicedToArray(_useState3, 2),
71
216
  sessionLoading = _useState4[0],
@@ -78,6 +223,8 @@ function useADKChat(_ref) {
78
223
  var _ref2 = config || {},
79
224
  appNo = _ref2.appNo,
80
225
  showFirstSession = _ref2.showFirstSession;
226
+ var pollSessionEvents = (_config$session$pollS = config === null || config === void 0 || (_config$session = config.session) === null || _config$session === void 0 ? void 0 : _config$session.pollSessionEvents) !== null && _config$session$pollS !== void 0 ? _config$session$pollS : true;
227
+ var sessionEventsPollingInterval = Math.max((_config$session$sessi = config === null || config === void 0 || (_config$session2 = config.session) === null || _config$session2 === void 0 ? void 0 : _config$session2.sessionEventsPollingInterval) !== null && _config$session$sessi !== void 0 ? _config$session$sessi : DEFAULT_SESSION_EVENTS_POLLING_INTERVAL, 1000);
81
228
  var _useState5 = useState(null),
82
229
  _useState6 = _slicedToArray(_useState5, 2),
83
230
  appInfo = _useState6[0],
@@ -122,6 +269,10 @@ function useADKChat(_ref) {
122
269
  _useState20 = _slicedToArray(_useState19, 2),
123
270
  messages = _useState20[0],
124
271
  setMessages = _useState20[1];
272
+ var pendingSessionEventsRef = useRef(null);
273
+ var sessionEventsFlushTimerRef = useRef(null);
274
+ var sessionEventsSyncingRef = useRef(false);
275
+ var sessionDetailLoadingRef = useRef(false);
125
276
  // 用户自定义业务参数 (stateDelta),每次发送请求时携带
126
277
  var stateDeltaRef = useRef(undefined);
127
278
 
@@ -151,6 +302,52 @@ function useADKChat(_ref) {
151
302
  }, [messages]);
152
303
  var textMsgRef = useRef(null);
153
304
  var eventDataRef = useRef(new Map());
305
+ var cancelSessionEventsFlush = useCallback(function () {
306
+ if (sessionEventsFlushTimerRef.current === null) return;
307
+ clearTimeout(sessionEventsFlushTimerRef.current);
308
+ sessionEventsFlushTimerRef.current = null;
309
+ }, []);
310
+ var flushPendingSessionEvents = useCallback(function () {
311
+ var pending = pendingSessionEventsRef.current;
312
+ var replyInProgress = loadingRef.current || sendingRef.current || textMsgRef.current !== null;
313
+ if (!pending || replyInProgress || pending.sessionId !== currentSessionIdRef.current) return;
314
+ var previewMessages = insertMissingSessionEvents(messagesRef.current, pending.events);
315
+ pendingSessionEventsRef.current = null;
316
+ if (previewMessages === messagesRef.current) return;
317
+ sessionEventsSyncingRef.current = true;
318
+ setLoading(true);
319
+ sessionEventsFlushTimerRef.current = setTimeout(function () {
320
+ sessionEventsFlushTimerRef.current = null;
321
+ if (pending.sessionId === currentSessionIdRef.current) {
322
+ setMessages(function (prev) {
323
+ var nextMessages = insertMissingSessionEvents(prev, pending.events);
324
+ messagesRef.current = nextMessages;
325
+ return nextMessages;
326
+ });
327
+ }
328
+ sessionEventsSyncingRef.current = false;
329
+ setLoading(false);
330
+ }, 0);
331
+ }, [setLoading]);
332
+ var syncSessionEvents = useCallback(function (events, targetSessionId) {
333
+ if (targetSessionId !== currentSessionIdRef.current) return;
334
+ pendingSessionEventsRef.current = {
335
+ sessionId: targetSessionId,
336
+ events: events
337
+ };
338
+ flushPendingSessionEvents();
339
+ }, [flushPendingSessionEvents]);
340
+ useEffect(function () {
341
+ pendingSessionEventsRef.current = null;
342
+ cancelSessionEventsFlush();
343
+ if (sessionEventsSyncingRef.current) {
344
+ sessionEventsSyncingRef.current = false;
345
+ setLoading(false);
346
+ }
347
+ }, [cancelSessionEventsFlush, currentSessionId, setLoading]);
348
+ useEffect(function () {
349
+ if (!loading) flushPendingSessionEvents();
350
+ }, [flushPendingSessionEvents, loading]);
154
351
 
155
352
  // 插入消息
156
353
  var insertMessage = useCallback(function (msg) {
@@ -345,9 +542,9 @@ function useADKChat(_ref) {
345
542
 
346
543
  // 处理建议类消息
347
544
  var processFollowupPart = useCallback(function (event) {
348
- var _event$content;
545
+ var _event$content3;
349
546
  // 获取建议类消息的文本内容
350
- var part = (event === null || event === void 0 || (_event$content = event.content) === null || _event$content === void 0 || (_event$content = _event$content.parts) === null || _event$content === void 0 ? void 0 : _event$content[0]) || null;
547
+ var part = (event === null || event === void 0 || (_event$content3 = event.content) === null || _event$content3 === void 0 || (_event$content3 = _event$content3.parts) === null || _event$content3 === void 0 ? void 0 : _event$content3[0]) || null;
351
548
  var text = (part === null || part === void 0 ? void 0 : part.text) || "";
352
549
  storeEvents(part, event);
353
550
  if (text) {
@@ -392,8 +589,10 @@ function useADKChat(_ref) {
392
589
 
393
590
  // 当 signal 被外部 abort(stopChat)时,确保外层 Promise 被 resolve
394
591
  // 否则 startChat 中的 await 会永远挂起,sendingRef 无法重置为 false
395
- newCtrl.signal.addEventListener('abort', function () {
592
+ newCtrl.signal.addEventListener("abort", function () {
396
593
  resolve();
594
+ }, {
595
+ once: true
397
596
  });
398
597
  var requestUrl = "".concat(url, "/api/gateway-web/openApi/v1/aizt/app/").concat(appNo, "/sendMsgStreaming");
399
598
 
@@ -420,7 +619,7 @@ function useADKChat(_ref) {
420
619
  } else if (response.status === 401 || response.status === 403) {
421
620
  setLoading(false);
422
621
  onError === null || onError === void 0 || onError({
423
- code: ErrorCode.API_ERROR,
622
+ code: ErrorCode.AUTH_ERROR,
424
623
  message: response.status === 401 ? "认证失败,token 无效或已过期" : "无权限访问该资源"
425
624
  });
426
625
  resolve();
@@ -603,7 +802,7 @@ function useADKChat(_ref) {
603
802
  while (1) switch (_context2.prev = _context2.next) {
604
803
  case 0:
605
804
  _ref3$text = _ref3.text, text = _ref3$text === void 0 ? "" : _ref3$text, _ref3$files = _ref3.files, files = _ref3$files === void 0 ? [] : _ref3$files, functionResponse = _ref3.functionResponse;
606
- if (!(loading || sendingRef.current)) {
805
+ if (!(loadingRef.current || sendingRef.current)) {
607
806
  _context2.next = 3;
608
807
  break;
609
808
  }
@@ -705,7 +904,7 @@ function useADKChat(_ref) {
705
904
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {
706
905
  while (1) switch (_context3.prev = _context3.next) {
707
906
  case 0:
708
- if (!(loading || sendingRef.current)) {
907
+ if (!(loadingRef.current || sendingRef.current)) {
709
908
  _context3.next = 2;
710
909
  break;
711
910
  }
@@ -789,7 +988,7 @@ function useADKChat(_ref) {
789
988
 
790
989
  // 使用建议问题
791
990
  var suggestChat = function suggestChat(text) {
792
- if (loading) return;
991
+ if (loadingRef.current) return;
793
992
  if (!text.trim()) return;
794
993
  setSuggestedQuestions([]);
795
994
  startChat({
@@ -800,11 +999,14 @@ function useADKChat(_ref) {
800
999
  // 停止会话(只中断前台连接)
801
1000
  var stopChat = useCallback(function () {
802
1001
  var _ctrl$current;
1002
+ pendingSessionEventsRef.current = null;
1003
+ cancelSessionEventsFlush();
1004
+ sessionEventsSyncingRef.current = false;
803
1005
  (_ctrl$current = ctrl.current) === null || _ctrl$current === void 0 || _ctrl$current.abort();
804
1006
  ctrl.current = null;
805
1007
  setLoading(false);
806
1008
  textMsgRef.current = null;
807
- }, []);
1009
+ }, [cancelSessionEventsFlush, setLoading]);
808
1010
 
809
1011
  // 清除/重置会话
810
1012
  var clearChat = function clearChat() {
@@ -819,118 +1021,13 @@ function useADKChat(_ref) {
819
1021
  };
820
1022
 
821
1023
  // 格式化会话记录
822
- var formatMessages = function formatMessages(messages) {
1024
+ var formatMessages = useCallback(function (sessionEvents) {
823
1025
  var isReplace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
824
- var mapped = [];
825
- messages.forEach(function (item) {
826
- if (!item || !item.content || !Array.isArray(item.content.parts)) return;
827
- var role = (item.content.role || "").toLowerCase() === "user" ? "user" : "bot";
828
- var parts = Array.isArray(item.content.parts) ? item.content.parts.filter(function (p) {
829
- if (!p) return false;
830
- return Boolean(p.text || p.inlineData || p.functionCall || p.functionResponse || p.fileData || p.executableCode || p.codeExecutionResult || p.errorMessage);
831
- }) : [];
832
- if (parts.length === 0) return;
833
-
834
- // 将同一条历史消息的 text/fileData parts 合并到一条 IMessage,避免拆分显示
835
- var textParts = parts.filter(function (p) {
836
- return p.text || p.errorMessage || p.inlineData;
837
- });
838
- var fileDataParts = parts.filter(function (p) {
839
- return p.fileData;
840
- });
841
- var otherParts = parts.filter(function (p) {
842
- return !p.text && !p.errorMessage && !p.inlineData && !p.fileData;
843
- });
844
-
845
- // 如果有 text/fileData,合并为一条消息
846
- if (textParts.length > 0 || fileDataParts.length > 0) {
847
- var msg = {
848
- id: v4(),
849
- author: item.author,
850
- invocationId: item.invocationId,
851
- eventId: item.id,
852
- timestamp: item.timestamp,
853
- isLike: item.isLike,
854
- role: role,
855
- modelCode: item.modelCode,
856
- usageMetadata: item.usageMetadata,
857
- finishReason: item.finishReason,
858
- raw: item
859
- };
860
- var _iterator4 = _createForOfIteratorHelper(textParts),
861
- _step4;
862
- try {
863
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
864
- var part = _step4.value;
865
- if (part.inlineData) {
866
- msg.inlineData = {
867
- displayName: part.inlineData.displayName,
868
- data: part.inlineData.data,
869
- mimeType: part.inlineData.mimeType
870
- };
871
- }
872
- if (part.text) {
873
- msg.text = (msg.text ? msg.text + "\n" : "") + part.text;
874
- if (typeof part.thought !== "undefined") msg.thought = part.thought;
875
- }
876
- if (part.errorMessage) {
877
- msg.text = (msg.text ? msg.text + "\n" : "") + part.errorMessage;
878
- }
879
- }
880
- } catch (err) {
881
- _iterator4.e(err);
882
- } finally {
883
- _iterator4.f();
884
- }
885
- if (fileDataParts.length > 0) {
886
- msg.fileData = fileDataParts.map(function (part) {
887
- return {
888
- displayName: part.fileData.displayName || "",
889
- fileUri: part.fileData.fileUri,
890
- mimeType: part.fileData.mimeType
891
- };
892
- });
893
- }
894
- mapped.push(msg);
895
- }
896
-
897
- // 处理其他类型的 parts(functionCall、executableCode 等)
898
- otherParts.forEach(function (part) {
899
- var msg = {
900
- id: v4(),
901
- author: item.author,
902
- invocationId: item.invocationId,
903
- eventId: item.id,
904
- timestamp: item.timestamp,
905
- isLike: item.isLike,
906
- role: role,
907
- modelCode: item.modelCode,
908
- usageMetadata: item.usageMetadata,
909
- finishReason: item.finishReason,
910
- raw: item
911
- };
912
- if (part.functionCall) msg.functionCall = part.functionCall;
913
- if (part.executableCode) msg.executableCode = part.executableCode;
914
- if (part.codeExecutionResult) msg.codeExecutionResult = part.codeExecutionResult;
915
- // 补全函数调用结果
916
- if (part.functionResponse) {
917
- // 通过 functionCall.id 寻找对应的函数调用消息,在那条消息上添加functionResponse
918
- var functionCallMsg = mapped.find(function (msg) {
919
- var _msg$functionCall2, _part$functionRespons;
920
- return ((_msg$functionCall2 = msg.functionCall) === null || _msg$functionCall2 === void 0 ? void 0 : _msg$functionCall2.id) === ((_part$functionRespons = part.functionResponse) === null || _part$functionRespons === void 0 ? void 0 : _part$functionRespons.id);
921
- });
922
- if (functionCallMsg) {
923
- functionCallMsg.functionResponse = part.functionResponse;
924
- }
925
- return;
926
- }
927
- mapped.push(msg);
928
- });
929
- });
1026
+ var mapped = mapSessionMessages(sessionEvents);
930
1027
  setMessages(function (prev) {
931
- return isReplace ? mapped : [].concat(_toConsumableArray(prev), mapped);
1028
+ return isReplace ? mapped : [].concat(_toConsumableArray(prev), _toConsumableArray(mapped));
932
1029
  });
933
- };
1030
+ }, []);
934
1031
 
935
1032
  // 设置当前会话详情
936
1033
  var setCurrentSession = /*#__PURE__*/function () {
@@ -940,7 +1037,7 @@ function useADKChat(_ref) {
940
1037
  while (1) switch (_context4.prev = _context4.next) {
941
1038
  case 0:
942
1039
  if (!sessionId) {
943
- _context4.next = 26;
1040
+ _context4.next = 34;
944
1041
  break;
945
1042
  }
946
1043
  if (!(sessionId === currentSessionId)) {
@@ -949,6 +1046,13 @@ function useADKChat(_ref) {
949
1046
  }
950
1047
  return _context4.abrupt("return");
951
1048
  case 3:
1049
+ pendingSessionEventsRef.current = null;
1050
+ cancelSessionEventsFlush();
1051
+ if (sessionEventsSyncingRef.current) {
1052
+ sessionEventsSyncingRef.current = false;
1053
+ setLoading(false);
1054
+ }
1055
+
952
1056
  // 1. 将当前会话挂起到后台(不中断 SSE 连接)
953
1057
  prevSessionId = currentSessionId;
954
1058
  if (ctrl.current) {
@@ -975,7 +1079,7 @@ function useADKChat(_ref) {
975
1079
  // 2. 尝试从后台恢复目标会话
976
1080
  bg = backgroundRef.current.get(sessionId);
977
1081
  if (!bg) {
978
- _context4.next = 15;
1082
+ _context4.next = 18;
979
1083
  break;
980
1084
  }
981
1085
  setMessages(bg.messages);
@@ -986,18 +1090,20 @@ function useADKChat(_ref) {
986
1090
  setInitialized(true);
987
1091
  backgroundRef.current.delete(sessionId);
988
1092
  return _context4.abrupt("return");
989
- case 15:
1093
+ case 18:
990
1094
  // 3. 后台没有目标 session,走 API 加载(原有逻辑)
991
1095
  setInitialized(false);
992
1096
  setCurrentSessionId(sessionId);
993
- _context4.next = 19;
1097
+ sessionDetailLoadingRef.current = true;
1098
+ _context4.prev = 21;
1099
+ _context4.next = 24;
994
1100
  return fetchSessionDetail({
995
1101
  url: url,
996
1102
  appNo: appNo,
997
1103
  sessionId: sessionId,
998
1104
  token: tokenRef.current
999
1105
  });
1000
- case 19:
1106
+ case 24:
1001
1107
  _yield$fetchSessionDe = _context4.sent;
1002
1108
  data = _yield$fetchSessionDe.data;
1003
1109
  result = _yield$fetchSessionDe.result;
@@ -1009,16 +1115,21 @@ function useADKChat(_ref) {
1009
1115
  setSuggestedQuestions((appInfo === null || appInfo === void 0 || (_appInfo$onboardingIn4 = appInfo.onboardingInfo) === null || _appInfo$onboardingIn4 === void 0 ? void 0 : _appInfo$onboardingIn4.suggested_questions) || []);
1010
1116
  }
1011
1117
  }
1118
+ case 28:
1119
+ _context4.prev = 28;
1120
+ sessionDetailLoadingRef.current = false;
1012
1121
  setInitialized(true);
1013
- _context4.next = 27;
1122
+ return _context4.finish(28);
1123
+ case 32:
1124
+ _context4.next = 35;
1014
1125
  break;
1015
- case 26:
1126
+ case 34:
1016
1127
  setCurrentSessionId(v4());
1017
- case 27:
1128
+ case 35:
1018
1129
  case "end":
1019
1130
  return _context4.stop();
1020
1131
  }
1021
- }, _callee4);
1132
+ }, _callee4, null, [[21,, 28, 32]]);
1022
1133
  }));
1023
1134
  return function setCurrentSession(_x2) {
1024
1135
  return _ref6.apply(this, arguments);
@@ -1100,6 +1211,12 @@ function useADKChat(_ref) {
1100
1211
  clearChat();
1101
1212
  }
1102
1213
  } else {
1214
+ // 服务端业务错误,透传原始 code + message 给接入方自行处理
1215
+ onError === null || onError === void 0 || onError({
1216
+ code: (result === null || result === void 0 ? void 0 : result.code) || "UNKNOWN_ERROR",
1217
+ message: (result === null || result === void 0 ? void 0 : result.message) || "获取会话列表失败",
1218
+ raw: result
1219
+ });
1103
1220
  setSessionList([]);
1104
1221
  setCurrentSessionId(v4());
1105
1222
  setPrologue("");
@@ -1111,7 +1228,7 @@ function useADKChat(_ref) {
1111
1228
  _context5.prev = 13;
1112
1229
  _context5.t0 = _context5["catch"](1);
1113
1230
  onError === null || onError === void 0 || onError({
1114
- code: ErrorCode.API_ERROR,
1231
+ code: ErrorCode.NETWORK_ERROR,
1115
1232
  message: "获取会话列表失败"
1116
1233
  });
1117
1234
  case 16:
@@ -1289,9 +1406,11 @@ function useADKChat(_ref) {
1289
1406
  message: "初始化配置成功"
1290
1407
  });
1291
1408
  } else {
1409
+ // 服务端业务错误,透传原始 code + message
1292
1410
  onError === null || onError === void 0 || onError({
1293
- code: result.code || ErrorCode.APP_NOT_FOUND,
1294
- message: result.message || "获取应用配置失败"
1411
+ code: result.code || "UNKNOWN_ERROR",
1412
+ message: result.message || "获取应用配置失败",
1413
+ raw: result
1295
1414
  });
1296
1415
  }
1297
1416
  _context9.next = 13;
@@ -1300,7 +1419,7 @@ function useADKChat(_ref) {
1300
1419
  _context9.prev = 10;
1301
1420
  _context9.t0 = _context9["catch"](0);
1302
1421
  onError === null || onError === void 0 || onError({
1303
- code: ErrorCode.API_ERROR,
1422
+ code: ErrorCode.NETWORK_ERROR,
1304
1423
  message: "获取应用配置失败"
1305
1424
  });
1306
1425
  case 13:
@@ -1333,10 +1452,72 @@ function useADKChat(_ref) {
1333
1452
  }
1334
1453
  }, [appInfo]);
1335
1454
 
1455
+ // 轮询当前会话详情,空闲时补入后端异步任务产生的模型消息。
1456
+ useEffect(function () {
1457
+ if (!enabled || !initialized || !pollSessionEvents || !appNo || !currentSessionId) return;
1458
+ var disposed = false;
1459
+ var requesting = false;
1460
+ var pollingSessionId = currentSessionId;
1461
+ var poll = /*#__PURE__*/function () {
1462
+ var _ref12 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10() {
1463
+ var _yield$fetchSessionDe2, data, result;
1464
+ return _regeneratorRuntime().wrap(function _callee10$(_context10) {
1465
+ while (1) switch (_context10.prev = _context10.next) {
1466
+ case 0:
1467
+ if (!(requesting || sessionDetailLoadingRef.current)) {
1468
+ _context10.next = 2;
1469
+ break;
1470
+ }
1471
+ return _context10.abrupt("return");
1472
+ case 2:
1473
+ requesting = true;
1474
+ _context10.prev = 3;
1475
+ _context10.next = 6;
1476
+ return fetchSessionDetail({
1477
+ url: url,
1478
+ appNo: appNo,
1479
+ sessionId: pollingSessionId,
1480
+ token: tokenRef.current
1481
+ });
1482
+ case 6:
1483
+ _yield$fetchSessionDe2 = _context10.sent;
1484
+ data = _yield$fetchSessionDe2.data;
1485
+ result = _yield$fetchSessionDe2.result;
1486
+ if (!disposed && (result === null || result === void 0 ? void 0 : result.code) === API_SUCCESS_CODE && Array.isArray(data)) {
1487
+ syncSessionEvents(data, pollingSessionId);
1488
+ }
1489
+ _context10.next = 14;
1490
+ break;
1491
+ case 12:
1492
+ _context10.prev = 12;
1493
+ _context10.t0 = _context10["catch"](3);
1494
+ case 14:
1495
+ _context10.prev = 14;
1496
+ requesting = false;
1497
+ return _context10.finish(14);
1498
+ case 17:
1499
+ case "end":
1500
+ return _context10.stop();
1501
+ }
1502
+ }, _callee10, null, [[3, 12, 14, 17]]);
1503
+ }));
1504
+ return function poll() {
1505
+ return _ref12.apply(this, arguments);
1506
+ };
1507
+ }();
1508
+ void poll();
1509
+ var timer = window.setInterval(poll, sessionEventsPollingInterval);
1510
+ return function () {
1511
+ disposed = true;
1512
+ window.clearInterval(timer);
1513
+ };
1514
+ }, [appNo, currentSessionId, enabled, initialized, pollSessionEvents, sessionEventsPollingInterval, syncSessionEvents, url]);
1515
+
1336
1516
  // 组件卸载时清理所有连接(前台 + 后台)
1337
1517
  useEffect(function () {
1338
1518
  return function () {
1339
1519
  var _ctrl$current2;
1520
+ cancelSessionEventsFlush();
1340
1521
  (_ctrl$current2 = ctrl.current) === null || _ctrl$current2 === void 0 || _ctrl$current2.abort();
1341
1522
  backgroundRef.current.forEach(function (bg) {
1342
1523
  var _bg$ctrl;
@@ -1344,7 +1525,7 @@ function useADKChat(_ref) {
1344
1525
  });
1345
1526
  backgroundRef.current.clear();
1346
1527
  };
1347
- }, []);
1528
+ }, [cancelSessionEventsFlush]);
1348
1529
  return {
1349
1530
  appInfo: appInfo,
1350
1531
  startChat: startChat,