@ai-group/chat-sdk 3.7.5 → 3.8.0-alpha.2

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 (117) hide show
  1. package/README.md +36 -0
  2. package/dist/cjs/components/DislikeFeedback.js.map +2 -2
  3. package/dist/cjs/components/FileGallery/index.js +2 -1
  4. package/dist/cjs/components/FileGallery/index.js.map +3 -3
  5. package/dist/cjs/components/FolderTree/DirectoryTree.js.map +2 -2
  6. package/dist/cjs/components/Sources/components/CarouselCard.js.map +2 -2
  7. package/dist/cjs/components/XAdkChatbot/index.js +307 -59
  8. package/dist/cjs/components/XAdkChatbot/index.js.map +3 -3
  9. package/dist/cjs/components/XAdkChatbot/styles.d.ts +4 -0
  10. package/dist/cjs/components/XAdkChatbot/styles.js +59 -2
  11. package/dist/cjs/components/XAdkChatbot/styles.js.map +2 -2
  12. package/dist/cjs/components/XAdkChatbot/utils.d.ts +14 -0
  13. package/dist/cjs/components/XAdkChatbot/utils.js +79 -0
  14. package/dist/cjs/components/XAdkChatbot/utils.js.map +7 -0
  15. package/dist/cjs/components/XAdkProvider/compound/DislikeFeedBack.js.map +2 -2
  16. package/dist/cjs/components/XAdkProvider/compound/Messages.d.ts +7 -1
  17. package/dist/cjs/components/XAdkProvider/compound/Messages.js +12 -0
  18. package/dist/cjs/components/XAdkProvider/compound/Messages.js.map +2 -2
  19. package/dist/cjs/components/XAdkProvider/compound/Sidebar.js.map +2 -2
  20. package/dist/cjs/components/XAdkProvider/context/ChatStateContext.d.ts +2 -0
  21. package/dist/cjs/components/XAdkProvider/context/ChatStateContext.js.map +2 -2
  22. package/dist/cjs/components/XAdkProvider/index.js +3 -0
  23. package/dist/cjs/components/XAdkProvider/index.js.map +2 -2
  24. package/dist/cjs/components/XAdkSender/InputTags.js.map +2 -2
  25. package/dist/cjs/components/XAdkSender/index.js +53 -5
  26. package/dist/cjs/components/XAdkSender/index.js.map +3 -3
  27. package/dist/cjs/components/XAdkThoughtChain/index.js +27 -28
  28. package/dist/cjs/components/XAdkThoughtChain/index.js.map +2 -2
  29. package/dist/cjs/components/XAdkThoughtChain/styles.d.ts +3 -1
  30. package/dist/cjs/components/XAdkThoughtChain/styles.js +66 -39
  31. package/dist/cjs/components/XAdkThoughtChain/styles.js.map +2 -2
  32. package/dist/cjs/components/XAiChatbot/index.js.map +2 -2
  33. package/dist/cjs/components/XAiConversations/index.js +2 -1
  34. package/dist/cjs/components/XAiConversations/index.js.map +3 -3
  35. package/dist/cjs/components/XAiProvider/index.js.map +2 -2
  36. package/dist/cjs/components/XAiSender/index.js.map +2 -2
  37. package/dist/cjs/hooks/useADKChat.d.ts +6 -1
  38. package/dist/cjs/hooks/useADKChat.js +15 -1
  39. package/dist/cjs/hooks/useADKChat.js.map +2 -2
  40. package/dist/cjs/hooks/useADKMessageQueue.d.ts +24 -0
  41. package/dist/cjs/hooks/useADKMessageQueue.js +107 -0
  42. package/dist/cjs/hooks/useADKMessageQueue.js.map +7 -0
  43. package/dist/cjs/index.d.ts +3 -1
  44. package/dist/cjs/index.js +3 -0
  45. package/dist/cjs/index.js.map +2 -2
  46. package/dist/cjs/react/index.d.ts +2 -0
  47. package/dist/cjs/react/index.js +3 -0
  48. package/dist/cjs/react/index.js.map +2 -2
  49. package/dist/cjs/types/XAdkChatbot.d.ts +49 -0
  50. package/dist/cjs/types/XAdkChatbot.js.map +1 -1
  51. package/dist/cjs/types/XAdkProvider.d.ts +7 -0
  52. package/dist/cjs/types/XAdkProvider.js.map +2 -2
  53. package/dist/cjs/types/XAdkSender.d.ts +8 -1
  54. package/dist/cjs/types/XAdkSender.js.map +1 -1
  55. package/dist/cjs/types/XAdkThoughtChain.d.ts +2 -0
  56. package/dist/cjs/types/XAdkThoughtChain.js.map +1 -1
  57. package/dist/cjs/types/antdx.d.ts +6 -3
  58. package/dist/cjs/types/antdx.js.map +1 -1
  59. package/dist/esm/components/DislikeFeedback.js.map +1 -1
  60. package/dist/esm/components/FileGallery/index.js +2 -1
  61. package/dist/esm/components/FileGallery/index.js.map +1 -1
  62. package/dist/esm/components/FolderTree/DirectoryTree.js.map +1 -1
  63. package/dist/esm/components/Sources/components/CarouselCard.js.map +1 -1
  64. package/dist/esm/components/XAdkChatbot/index.js +277 -25
  65. package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
  66. package/dist/esm/components/XAdkChatbot/styles.d.ts +4 -0
  67. package/dist/esm/components/XAdkChatbot/styles.js +30 -26
  68. package/dist/esm/components/XAdkChatbot/styles.js.map +1 -1
  69. package/dist/esm/components/XAdkChatbot/utils.d.ts +14 -0
  70. package/dist/esm/components/XAdkChatbot/utils.js +66 -0
  71. package/dist/esm/components/XAdkChatbot/utils.js.map +1 -0
  72. package/dist/esm/components/XAdkProvider/compound/DislikeFeedBack.js.map +1 -1
  73. package/dist/esm/components/XAdkProvider/compound/Messages.d.ts +7 -1
  74. package/dist/esm/components/XAdkProvider/compound/Messages.js +16 -2
  75. package/dist/esm/components/XAdkProvider/compound/Messages.js.map +1 -1
  76. package/dist/esm/components/XAdkProvider/compound/Sidebar.js.map +1 -1
  77. package/dist/esm/components/XAdkProvider/context/ChatStateContext.d.ts +2 -0
  78. package/dist/esm/components/XAdkProvider/context/ChatStateContext.js.map +1 -1
  79. package/dist/esm/components/XAdkProvider/index.js +4 -2
  80. package/dist/esm/components/XAdkProvider/index.js.map +1 -1
  81. package/dist/esm/components/XAdkSender/InputTags.js.map +1 -1
  82. package/dist/esm/components/XAdkSender/index.js +80 -16
  83. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  84. package/dist/esm/components/XAdkThoughtChain/index.js +52 -78
  85. package/dist/esm/components/XAdkThoughtChain/index.js.map +1 -1
  86. package/dist/esm/components/XAdkThoughtChain/styles.d.ts +3 -1
  87. package/dist/esm/components/XAdkThoughtChain/styles.js +29 -27
  88. package/dist/esm/components/XAdkThoughtChain/styles.js.map +1 -1
  89. package/dist/esm/components/XAiChatbot/index.js.map +1 -1
  90. package/dist/esm/components/XAiConversations/index.js +2 -1
  91. package/dist/esm/components/XAiConversations/index.js.map +1 -1
  92. package/dist/esm/components/XAiProvider/index.js.map +1 -1
  93. package/dist/esm/components/XAiSender/index.js.map +1 -1
  94. package/dist/esm/hooks/useADKChat.d.ts +6 -1
  95. package/dist/esm/hooks/useADKChat.js +18 -1
  96. package/dist/esm/hooks/useADKChat.js.map +1 -1
  97. package/dist/esm/hooks/useADKMessageQueue.d.ts +24 -0
  98. package/dist/esm/hooks/useADKMessageQueue.js +159 -0
  99. package/dist/esm/hooks/useADKMessageQueue.js.map +1 -0
  100. package/dist/esm/index.d.ts +3 -1
  101. package/dist/esm/index.js +2 -1
  102. package/dist/esm/index.js.map +1 -1
  103. package/dist/esm/react/index.d.ts +2 -0
  104. package/dist/esm/react/index.js +1 -0
  105. package/dist/esm/react/index.js.map +1 -1
  106. package/dist/esm/types/XAdkChatbot.d.ts +49 -0
  107. package/dist/esm/types/XAdkChatbot.js.map +1 -1
  108. package/dist/esm/types/XAdkProvider.d.ts +7 -0
  109. package/dist/esm/types/XAdkProvider.js.map +1 -1
  110. package/dist/esm/types/XAdkSender.d.ts +8 -1
  111. package/dist/esm/types/XAdkSender.js.map +1 -1
  112. package/dist/esm/types/XAdkThoughtChain.d.ts +2 -0
  113. package/dist/esm/types/XAdkThoughtChain.js.map +1 -1
  114. package/dist/esm/types/antdx.d.ts +6 -3
  115. package/dist/esm/types/antdx.js.map +1 -1
  116. package/dist/umd/chat-sdk.min.js +1 -1
  117. package/package.json +1 -1
@@ -1,11 +1,12 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
3
- import { useMemo, useCallback, useEffect, useRef, useImperativeHandle, forwardRef } from "react";
3
+ import { useMemo, useCallback, useEffect, useLayoutEffect, useRef, useImperativeHandle, forwardRef, Fragment } from "react";
4
4
  import { Button, Flex, Tooltip, message as antdMessage } from "antd";
5
5
  import clsx from "clsx";
6
6
  import { SwapRightOutlined, ReloadOutlined, CopyOutlined, InfoCircleOutlined } from "@ant-design/icons";
7
7
  import copy from "copy-to-clipboard";
8
8
  import { useStyles } from "./styles";
9
+ import { formatTimestamp, getSelectionText } from "./utils";
9
10
  import MarkdownRender from "./components/MarkdownRender";
10
11
  import FunctionCallRender from "./components/FunctionCallRender";
11
12
  import FileGallery from "../FileGallery";
@@ -29,12 +30,16 @@ var scrollThreshold = 10;
29
30
  * - ✅ 欢迎页面 (agentName/agentIcon/description)
30
31
  */
31
32
  var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
32
- var _mergedStrategies$par;
33
+ var _mergedStrategies$par, _history$direction;
33
34
  var _ref$loading = _ref.loading,
34
35
  loading = _ref$loading === void 0 ? false : _ref$loading,
35
36
  prologue = _ref.prologue,
36
37
  suggestions = _ref.suggestions,
37
38
  messages = _ref.messages,
39
+ renderBeforeGroup = _ref.renderBeforeGroup,
40
+ renderAfterGroup = _ref.renderAfterGroup,
41
+ renderGroup = _ref.renderGroup,
42
+ history = _ref.history,
38
43
  showFnCallDetail = _ref.showFnCallDetail,
39
44
  onConfirm = _ref.onConfirm,
40
45
  onSuggest = _ref.onSuggest,
@@ -64,7 +69,9 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
64
69
  toolKindResolver = _ref.toolKindResolver,
65
70
  strategies = _ref.strategies,
66
71
  preset = _ref.preset,
67
- empty = _ref.empty;
72
+ empty = _ref.empty,
73
+ showUserActions = _ref.showUserActions,
74
+ userActions = _ref.userActions;
68
75
  var styles = useStyles();
69
76
  var listRef = useRef(null);
70
77
  var lastScrollTopRef = useRef(0);
@@ -73,6 +80,98 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
73
80
  var prevInitializedRef = useRef(false);
74
81
  var prevSessionIdRef = useRef(sessionId);
75
82
  var previousMessageCountRef = useRef(messages.length);
83
+ var historyRef = useRef(history);
84
+ historyRef.current = history;
85
+ var messagesRef = useRef(messages);
86
+ messagesRef.current = messages;
87
+ var historyRequestRef = useRef(false);
88
+ var historyRequestIdRef = useRef(0);
89
+ var historyRequestControllerRef = useRef(null);
90
+ var historyRefreshRef = useRef(false);
91
+ var historyRefreshIdRef = useRef(0);
92
+ var historyRefreshControllerRef = useRef(null);
93
+ var prependAnchorRef = useRef(null);
94
+ var skipNextAutoScrollRef = useRef(false);
95
+ var prependExpiryRef = useRef(null);
96
+ var loadMoreHistory = useCallback(function () {
97
+ var _pagination$direction;
98
+ var pagination = historyRef.current;
99
+ var el = listRef.current;
100
+ if (!(pagination !== null && pagination !== void 0 && pagination.hasMore) || pagination.loading || historyRequestRef.current || !el) return;
101
+ var direction = (_pagination$direction = pagination.direction) !== null && _pagination$direction !== void 0 ? _pagination$direction : "top";
102
+ if (direction === "top") {
103
+ var _currentMessages$;
104
+ if (prependExpiryRef.current) clearTimeout(prependExpiryRef.current);
105
+ var currentMessages = messagesRef.current;
106
+ prependAnchorRef.current = {
107
+ sessionId: prevSessionIdRef.current,
108
+ firstMessageId: (_currentMessages$ = currentMessages[0]) === null || _currentMessages$ === void 0 ? void 0 : _currentMessages$.id,
109
+ messageCount: currentMessages.length,
110
+ scrollTop: el.scrollTop,
111
+ scrollHeight: el.scrollHeight
112
+ };
113
+ }
114
+ historyRequestRef.current = true;
115
+ var requestId = ++historyRequestIdRef.current;
116
+ var controller = new AbortController();
117
+ historyRequestControllerRef.current = controller;
118
+ void Promise.resolve().then(function () {
119
+ return pagination.onLoadMore({
120
+ signal: controller.signal
121
+ });
122
+ }).catch(function () {
123
+ if (requestId !== historyRequestIdRef.current || controller.signal.aborted) return;
124
+ prependAnchorRef.current = null;
125
+ antdMessage.error("加载历史消息失败,请重试");
126
+ }).finally(function () {
127
+ if (requestId === historyRequestIdRef.current) {
128
+ historyRequestRef.current = false;
129
+ historyRequestControllerRef.current = null;
130
+ // 没有新页时解除滚动锚点,避免后续正常消息被误认为 prepend。
131
+ prependExpiryRef.current = setTimeout(function () {
132
+ prependAnchorRef.current = null;
133
+ prependExpiryRef.current = null;
134
+ }, 500);
135
+ }
136
+ });
137
+ }, []);
138
+ var refreshHistory = useCallback(function () {
139
+ var pagination = historyRef.current;
140
+ if (!(pagination !== null && pagination !== void 0 && pagination.onRefresh) || pagination.refreshing || historyRefreshRef.current) return;
141
+ historyRefreshRef.current = true;
142
+ var requestId = ++historyRefreshIdRef.current;
143
+ var controller = new AbortController();
144
+ historyRefreshControllerRef.current = controller;
145
+ void Promise.resolve().then(function () {
146
+ var _pagination$onRefresh;
147
+ return (_pagination$onRefresh = pagination.onRefresh) === null || _pagination$onRefresh === void 0 ? void 0 : _pagination$onRefresh.call(pagination, {
148
+ signal: controller.signal
149
+ });
150
+ }).catch(function () {
151
+ if (!controller.signal.aborted) antdMessage.error("刷新历史消息失败,请重试");
152
+ }).finally(function () {
153
+ if (requestId === historyRefreshIdRef.current) {
154
+ historyRefreshRef.current = false;
155
+ historyRefreshControllerRef.current = null;
156
+ }
157
+ });
158
+ }, []);
159
+ useLayoutEffect(function () {
160
+ var _messages$;
161
+ var anchor = prependAnchorRef.current;
162
+ var el = listRef.current;
163
+ if (!anchor || !el) return;
164
+ if (anchor.sessionId !== sessionId) {
165
+ prependAnchorRef.current = null;
166
+ return;
167
+ }
168
+ if (messages.length <= anchor.messageCount || ((_messages$ = messages[0]) === null || _messages$ === void 0 ? void 0 : _messages$.id) === anchor.firstMessageId) return;
169
+ el.scrollTop = anchor.scrollTop + el.scrollHeight - anchor.scrollHeight;
170
+ skipNextAutoScrollRef.current = true;
171
+ prependAnchorRef.current = null;
172
+ if (prependExpiryRef.current) clearTimeout(prependExpiryRef.current);
173
+ prependExpiryRef.current = null;
174
+ }, [messages, sessionId]);
76
175
 
77
176
  // 暴露命令式 API
78
177
  var scrollToBottom = useCallback(function () {
@@ -82,11 +181,35 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
82
181
  behavior: behavior
83
182
  });
84
183
  }, []);
184
+ var getScrollContainer = useCallback(function () {
185
+ return listRef.current;
186
+ }, []);
187
+ var getMessagePosition = useCallback(function (messageId) {
188
+ var list = listRef.current;
189
+ if (!list) return null;
190
+ var group = Array.from(list.children).find(function (element) {
191
+ return element instanceof HTMLElement && element.dataset.messageId === messageId;
192
+ });
193
+ if (!group) return null;
194
+ return group.getBoundingClientRect().top - list.getBoundingClientRect().top + list.scrollTop;
195
+ }, []);
196
+ var scrollToMessage = useCallback(function (messageId) {
197
+ var behavior = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "smooth";
198
+ var list = listRef.current;
199
+ var top = getMessagePosition(messageId);
200
+ if (list && top !== null) list.scrollTo({
201
+ top: top,
202
+ behavior: behavior
203
+ });
204
+ }, [getMessagePosition]);
85
205
  useImperativeHandle(ref, function () {
86
206
  return {
87
- scrollToBottom: scrollToBottom
207
+ scrollToBottom: scrollToBottom,
208
+ getScrollContainer: getScrollContainer,
209
+ getMessagePosition: getMessagePosition,
210
+ scrollToMessage: scrollToMessage
88
211
  };
89
- }, [scrollToBottom]);
212
+ }, [scrollToBottom, getScrollContainer, getMessagePosition, scrollToMessage]);
90
213
  var mergedStrategies = useMemo(function () {
91
214
  return mergeChatStrategies(preset, strategies);
92
215
  }, [preset, strategies]);
@@ -147,18 +270,40 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
147
270
 
148
271
  // 会话切换时重置滚动状态,允许重新触发初始化置底
149
272
  useEffect(function () {
273
+ var _historyRequestContro, _historyRefreshContro;
150
274
  if (sessionId === undefined) return; // 未传 sessionId 不处理
151
275
  if (prevSessionIdRef.current === sessionId) return; // 同一会话不处理
152
276
  prevSessionIdRef.current = sessionId;
153
277
  prevInitializedRef.current = false;
154
278
  userHasScrolledRef.current = false;
279
+ (_historyRequestContro = historyRequestControllerRef.current) === null || _historyRequestContro === void 0 || _historyRequestContro.abort();
280
+ (_historyRefreshContro = historyRefreshControllerRef.current) === null || _historyRefreshContro === void 0 || _historyRefreshContro.abort();
281
+ prependAnchorRef.current = null;
282
+ historyRequestRef.current = false;
283
+ historyRequestIdRef.current += 1;
284
+ historyRefreshRef.current = false;
285
+ historyRefreshIdRef.current += 1;
286
+ if (prependExpiryRef.current) clearTimeout(prependExpiryRef.current);
287
+ prependExpiryRef.current = null;
155
288
  }, [sessionId]);
289
+ useEffect(function () {
290
+ return function () {
291
+ var _historyRequestContro2, _historyRefreshContro2;
292
+ (_historyRequestContro2 = historyRequestControllerRef.current) === null || _historyRequestContro2 === void 0 || _historyRequestContro2.abort();
293
+ (_historyRefreshContro2 = historyRefreshControllerRef.current) === null || _historyRefreshContro2 === void 0 || _historyRefreshContro2.abort();
294
+ if (prependExpiryRef.current) clearTimeout(prependExpiryRef.current);
295
+ };
296
+ }, []);
156
297
 
157
298
  // 新增用户消息代表一次主动发送,应无条件恢复跟随并置底。
158
299
  // 之后的流式回复继续沿用“用户未主动上滚时跟随”的规则。
159
300
  useEffect(function () {
160
301
  var previousCount = previousMessageCountRef.current;
161
302
  previousMessageCountRef.current = messages.length;
303
+ if (skipNextAutoScrollRef.current || prependAnchorRef.current) {
304
+ skipNextAutoScrollRef.current = false;
305
+ return;
306
+ }
162
307
  var hasNewUserMessage = messages.slice(previousCount).some(function (message) {
163
308
  return message.role === "user";
164
309
  });
@@ -207,8 +352,15 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
207
352
  if (isAtBottom) {
208
353
  userHasScrolledRef.current = false;
209
354
  }
355
+ var pagination = historyRef.current;
356
+ if (pagination !== null && pagination !== void 0 && pagination.hasMore) {
357
+ var _pagination$threshold, _pagination$direction2;
358
+ var threshold = (_pagination$threshold = pagination.threshold) !== null && _pagination$threshold !== void 0 ? _pagination$threshold : 80;
359
+ var atLoadEdge = ((_pagination$direction2 = pagination.direction) !== null && _pagination$direction2 !== void 0 ? _pagination$direction2 : "top") === "top" ? currentTop <= threshold : el.scrollHeight - currentTop - el.clientHeight <= threshold;
360
+ if (atLoadEdge) loadMoreHistory();
361
+ }
210
362
  lastScrollTopRef.current = currentTop;
211
- }, []);
363
+ }, [loadMoreHistory]);
212
364
  useEffect(function () {
213
365
  var listElement = listRef.current;
214
366
  if (!listElement) return;
@@ -218,6 +370,13 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
218
370
  };
219
371
  }, [handleScroll]);
220
372
 
373
+ // 首屏内容不足一屏时没有滚动事件,继续按需加载直到内容可滚动或数据耗尽。
374
+ useEffect(function () {
375
+ if (!initialized || !(history !== null && history !== void 0 && history.hasMore) || history.loading) return;
376
+ var el = listRef.current;
377
+ if (el && el.scrollHeight <= el.clientHeight + 1) loadMoreHistory();
378
+ }, [history === null || history === void 0 ? void 0 : history.hasMore, history === null || history === void 0 ? void 0 : history.loading, initialized, loadMoreHistory, messages]);
379
+
221
380
  // ========== 消息分组逻辑 ==========
222
381
  var chatGroups = useMemo(function () {
223
382
  if (!enableGrouping) {
@@ -274,12 +433,14 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
274
433
 
275
434
  // ========== 渲染 Bot 消息组 ==========
276
435
  var renderBotGroup = useCallback(function (group, isLastGroup, renderFunctionCall) {
436
+ var _activeItem$msg, _activeItem$msg2, _activeItem$msg3;
277
437
  var msgs = group.msgs,
278
438
  allFiles = group.allFiles;
279
439
  if (!enableProcessParsing) {
280
440
  // 不解析 process,简单渲染
281
441
  return /*#__PURE__*/_jsx("div", {
282
442
  className: styles.botMsg,
443
+ "data-message-id": group.id,
283
444
  children: msgs.map(function (msg, i) {
284
445
  if (msg.text) {
285
446
  return /*#__PURE__*/_jsx(MarkdownRender, {
@@ -420,9 +581,7 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
420
581
  return m.text || "";
421
582
  }).join("");
422
583
  var lastBotMsg = msgs[msgs.length - 1];
423
- var hasProcess = nodes.some(function (n) {
424
- return n.type === "process";
425
- });
584
+ // const hasProcess = nodes.some((n) => n.type === "process");
426
585
  var isGroupLoading = loading && isLastGroup;
427
586
  var actionProps = {
428
587
  message: group,
@@ -431,22 +590,44 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
431
590
  var actionExtraNode = actionsExtra === null || actionsExtra === void 0 ? void 0 : actionsExtra(actionProps);
432
591
 
433
592
  // 4. 渲染
593
+ // 确认 [规划, 工具调用, 中途说明, 工具调用, 最终回答]
594
+ var firstProcessIdx = nodes.findIndex(function (n) {
595
+ return n.type === "process";
596
+ });
434
597
  var lastProcessIdx = nodes.findLastIndex(function (n) {
435
598
  return n.type === "process";
436
599
  });
600
+ var processItems = nodes.slice(firstProcessIdx, lastProcessIdx + 1).flatMap(function (node) {
601
+ return node.type === "process" ? node.items : [{
602
+ type: "text",
603
+ key: node.key,
604
+ title: "过程分析",
605
+ content: node.content
606
+ }];
607
+ });
608
+ var activeItem = processItems[processItems.length - 1];
609
+ var activeStep = (activeItem === null || activeItem === void 0 ? void 0 : activeItem.type) === "tool" ? String(((_activeItem$msg = activeItem.msg) === null || _activeItem$msg === void 0 || (_activeItem$msg = _activeItem$msg.functionCall) === null || _activeItem$msg === void 0 || (_activeItem$msg = _activeItem$msg.args) === null || _activeItem$msg === void 0 ? void 0 : _activeItem$msg.agentName) || ((_activeItem$msg2 = activeItem.msg) === null || _activeItem$msg2 === void 0 || (_activeItem$msg2 = _activeItem$msg2.functionCall) === null || _activeItem$msg2 === void 0 || (_activeItem$msg2 = _activeItem$msg2.args) === null || _activeItem$msg2 === void 0 ? void 0 : _activeItem$msg2.componentName) || ((_activeItem$msg3 = activeItem.msg) === null || _activeItem$msg3 === void 0 || (_activeItem$msg3 = _activeItem$msg3.functionCall) === null || _activeItem$msg3 === void 0 ? void 0 : _activeItem$msg3.name) || "") : typeof (activeItem === null || activeItem === void 0 ? void 0 : activeItem.title) === "string" ? activeItem.title : "";
437
610
  return /*#__PURE__*/_jsxs("div", {
438
611
  className: styles.botMsg,
612
+ "data-message-id": group.id,
439
613
  children: [nodes.map(function (node, idx) {
614
+ if (node.type === "text" && idx > firstProcessIdx && idx < lastProcessIdx) {
615
+ return null;
616
+ }
440
617
  if (node.type === "process") {
441
- // 只有最后一个 process node 跟随 loading 状态,已完成的思维链不应显示 loading
442
- var isLastProcess = idx === lastProcessIdx;
618
+ // 同一轮回复中的过程节点共用一个容器,保留节点自身的执行顺序。
619
+ if (idx !== firstProcessIdx) {
620
+ return null;
621
+ }
443
622
  return /*#__PURE__*/_jsx(XAdkThoughtChain, {
444
- loading: isLastProcess && isGroupLoading,
445
- title: "\u601D\u7EF4\u94FE\u5DF2\u5B8C\u6210",
446
- items: node.items,
623
+ collapsible: true,
624
+ loading: isGroupLoading,
625
+ title: "\u5DF2\u5B8C\u6210",
626
+ activeStep: activeStep,
627
+ items: processItems,
447
628
  showFnCallDetail: showFnCallDetail,
448
629
  onConfirm: onConfirm,
449
- defaultOpen: isLastProcess && isGroupLoading,
630
+ defaultOpen: isGroupLoading,
450
631
  renderFunctionCall: renderFunctionCall,
451
632
  toolKindResolver: function toolKindResolver(name) {
452
633
  return resolveToolKind(name);
@@ -521,10 +702,25 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
521
702
  }, [enableProcessParsing, parseOptions, parseProcessMessage, showFnCallDetail, onConfirm, loading, showRetry, showCopy, showLog, onRetry, onCopy, onShowLog, actions, actionsExtra, onFileClick, onResourceLinkClick, renderResourceLink, mergedMarkdownExtensions, resourceLinkSchemes, styles, resolveToolKind, mergedStrategies]);
522
703
 
523
704
  // ========== 渲染用户消息组 ==========
524
- var renderUserGroup = useCallback(function (group) {
525
- return /*#__PURE__*/_jsx("div", {
705
+ var renderUserGroup = useCallback(function (group, nextGroup) {
706
+ var _userActions, _group$msgs;
707
+ var compactWithNextText = group.msgs.some(function (message) {
708
+ var _message$fileData;
709
+ return Boolean((_message$fileData = message.fileData) === null || _message$fileData === void 0 ? void 0 : _message$fileData.length);
710
+ }) && group.msgs.every(function (message) {
711
+ var _message$text;
712
+ return !((_message$text = message.text) !== null && _message$text !== void 0 && _message$text.trim());
713
+ }) && (nextGroup === null || nextGroup === void 0 ? void 0 : nextGroup.role) === "user" && nextGroup.msgs.some(function (message) {
714
+ var _message$text2;
715
+ return Boolean((_message$text2 = message.text) === null || _message$text2 === void 0 ? void 0 : _message$text2.trim());
716
+ });
717
+ return /*#__PURE__*/_jsxs("div", {
526
718
  className: styles.userMsg,
527
- children: group.msgs.map(function (m, i) {
719
+ "data-message-id": group.id,
720
+ style: compactWithNextText ? {
721
+ marginBottom: 8
722
+ } : undefined,
723
+ children: [group.msgs.map(function (m, i) {
528
724
  return /*#__PURE__*/_jsxs("div", {
529
725
  className: styles.userContainer,
530
726
  children: [m.fileData && m.fileData.length > 0 && /*#__PURE__*/_jsx(_Fragment, {
@@ -533,18 +729,21 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
533
729
  file: file,
534
730
  align: "left",
535
731
  style: {
536
- marginBottom: "16px"
732
+ marginBottom: compactWithNextText && i === group.msgs.length - 1 && index === m.fileData.length - 1 ? 0 : 16
537
733
  },
538
734
  onClick: onFileClick
539
735
  }, index);
540
736
  })
541
737
  }), m.text && /*#__PURE__*/_jsx("div", {
542
738
  className: styles.card,
739
+ "data-xadk-user-card": true,
543
740
  onCopy: function onCopy(event) {
544
741
  // 富文本标签的可见文案不含协议;复制用户消息时保留原始 Markdown,
545
742
  // 使内容粘贴回 XAdkSender 后能重新还原成 Mention。
743
+ // 若有选区则只复制选区内容(变量模块取完整文案),否则复制全量。
546
744
  event.preventDefault();
547
- event.clipboardData.setData("text/plain", m.text || "");
745
+ var selected = getSelectionText(event.currentTarget);
746
+ event.clipboardData.setData("text/plain", selected || m.text || "");
548
747
  },
549
748
  children: /*#__PURE__*/_jsx(MarkdownRender, {
550
749
  text: m.text,
@@ -559,9 +758,36 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
559
758
  })
560
759
  })]
561
760
  }, m.id || i);
562
- })
761
+ }), showUserActions && group.msgs.some(function (message) {
762
+ var _message$text3;
763
+ return Boolean((_message$text3 = message.text) === null || _message$text3 === void 0 ? void 0 : _message$text3.trim());
764
+ }) && /*#__PURE__*/_jsx("div", {
765
+ className: "x-user-actions ".concat(styles.userActions),
766
+ children: (_userActions = userActions === null || userActions === void 0 ? void 0 : userActions({
767
+ message: group
768
+ })) !== null && _userActions !== void 0 ? _userActions : /*#__PURE__*/_jsxs(_Fragment, {
769
+ children: [/*#__PURE__*/_jsx("span", {
770
+ className: styles.userTime,
771
+ children: formatTimestamp((_group$msgs = group.msgs[group.msgs.length - 1]) === null || _group$msgs === void 0 ? void 0 : _group$msgs.timestamp)
772
+ }), /*#__PURE__*/_jsx(Tooltip, {
773
+ title: "\u590D\u5236\u5185\u5BB9",
774
+ children: /*#__PURE__*/_jsx(CopyOutlined, {
775
+ className: styles.userActionIcon,
776
+ onClick: function onClick() {
777
+ var container = document.querySelector("[data-message-id=\"".concat(group.id, "\"]"));
778
+ var selected = getSelectionText(container);
779
+ var fullText = group.msgs.map(function (message) {
780
+ return message.text || "";
781
+ }).join("");
782
+ copy(selected || fullText);
783
+ antdMessage.success("复制成功");
784
+ }
785
+ })
786
+ })]
787
+ })
788
+ })]
563
789
  }, group.id);
564
- }, [styles, onFileClick, onResourceLinkClick, renderResourceLink, mergedMarkdownExtensions, resourceLinkSchemes]);
790
+ }, [styles, onFileClick, onResourceLinkClick, renderResourceLink, mergedMarkdownExtensions, resourceLinkSchemes, showUserActions, userActions]);
565
791
 
566
792
  // ========== 空状态 ==========
567
793
 
@@ -601,6 +827,20 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
601
827
 
602
828
  // 空状态判断
603
829
  var isEmpty = messages.length === 0 && !prologue && (!suggestions || suggestions.length === 0);
830
+ var historyControls = history && (history.hasMore || history.loading || history.onRefresh) && /*#__PURE__*/_jsxs("div", {
831
+ className: styles.historyControls,
832
+ children: [history.onRefresh && /*#__PURE__*/_jsx("button", {
833
+ type: "button",
834
+ onClick: refreshHistory,
835
+ disabled: history.refreshing,
836
+ children: history.refreshing ? "正在刷新..." : "刷新"
837
+ }), (history.hasMore || history.loading) && /*#__PURE__*/_jsx("button", {
838
+ type: "button",
839
+ onClick: loadMoreHistory,
840
+ disabled: history.loading,
841
+ children: history.loading ? "正在加载..." : "加载更多"
842
+ })]
843
+ });
604
844
  return /*#__PURE__*/_jsxs("div", {
605
845
  className: clsx(styles.wrapper, className),
606
846
  style: style,
@@ -613,7 +853,7 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
613
853
  style: isEmpty ? {
614
854
  flex: 0
615
855
  } : undefined,
616
- children: [prologue && /*#__PURE__*/_jsx("div", {
856
+ children: [((_history$direction = history === null || history === void 0 ? void 0 : history.direction) !== null && _history$direction !== void 0 ? _history$direction : "top") === "top" && historyControls, prologue && /*#__PURE__*/_jsx("div", {
617
857
  className: styles.prologue,
618
858
  children: /*#__PURE__*/_jsx(MarkdownRender, {
619
859
  text: prologue,
@@ -624,8 +864,20 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
624
864
  markdownExtensions: mergedMarkdownExtensions
625
865
  })
626
866
  }), chatGroups.map(function (group, idx) {
627
- return group.role === "user" ? renderUserGroup(group) : renderBotGroup(group, idx === chatGroups.length - 1, renderFunctionCall);
628
- }), renderSuggestions(), /*#__PURE__*/_jsx("div", {
867
+ var context = {
868
+ group: group,
869
+ index: idx,
870
+ previousGroup: chatGroups[idx - 1],
871
+ nextGroup: chatGroups[idx + 1]
872
+ };
873
+ var defaultNode = group.role === "user" ? renderUserGroup(group, chatGroups[idx + 1]) : renderBotGroup(group, idx === chatGroups.length - 1, renderFunctionCall);
874
+ var customNode = renderGroup === null || renderGroup === void 0 ? void 0 : renderGroup(_objectSpread(_objectSpread({}, context), {}, {
875
+ defaultNode: defaultNode
876
+ }));
877
+ return /*#__PURE__*/_jsxs(Fragment, {
878
+ children: [renderBeforeGroup === null || renderBeforeGroup === void 0 ? void 0 : renderBeforeGroup(context), customNode === undefined ? defaultNode : customNode, renderAfterGroup === null || renderAfterGroup === void 0 ? void 0 : renderAfterGroup(context)]
879
+ }, group.id);
880
+ }), (history === null || history === void 0 ? void 0 : history.direction) === "bottom" && historyControls, renderSuggestions(), /*#__PURE__*/_jsx("div", {
629
881
  ref: messagesEndRef
630
882
  })]
631
883
  })]