@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
@@ -38,11 +38,12 @@ var import_clsx = __toESM(require("clsx"));
38
38
  var import_icons = require("@ant-design/icons");
39
39
  var import_copy_to_clipboard = __toESM(require("copy-to-clipboard"));
40
40
  var import_styles = require("./styles");
41
+ var import_utils = require("./utils");
41
42
  var import_MarkdownRender = __toESM(require("./components/MarkdownRender"));
42
43
  var import_FunctionCallRender = __toESM(require("./components/FunctionCallRender"));
43
44
  var import_FileGallery = __toESM(require("../FileGallery"));
44
45
  var import_XAdkThoughtChain = __toESM(require("../XAdkThoughtChain"));
45
- var import_utils = require("../../utils");
46
+ var import_utils2 = require("../../utils");
46
47
  var import_runtime = require("../../presets/runtime");
47
48
  var import_FunctionCallRender2 = require("../../types/FunctionCallRender");
48
49
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -53,6 +54,10 @@ var XAdkChatbot = (0, import_react.forwardRef)(
53
54
  prologue,
54
55
  suggestions,
55
56
  messages,
57
+ renderBeforeGroup,
58
+ renderAfterGroup,
59
+ renderGroup,
60
+ history,
56
61
  showFnCallDetail,
57
62
  onConfirm,
58
63
  onSuggest,
@@ -80,7 +85,9 @@ var XAdkChatbot = (0, import_react.forwardRef)(
80
85
  toolKindResolver,
81
86
  strategies,
82
87
  preset,
83
- empty
88
+ empty,
89
+ showUserActions,
90
+ userActions
84
91
  }, ref) => {
85
92
  const styles = (0, import_styles.useStyles)();
86
93
  const listRef = (0, import_react.useRef)(null);
@@ -90,11 +97,128 @@ var XAdkChatbot = (0, import_react.forwardRef)(
90
97
  const prevInitializedRef = (0, import_react.useRef)(false);
91
98
  const prevSessionIdRef = (0, import_react.useRef)(sessionId);
92
99
  const previousMessageCountRef = (0, import_react.useRef)(messages.length);
100
+ const historyRef = (0, import_react.useRef)(history);
101
+ historyRef.current = history;
102
+ const messagesRef = (0, import_react.useRef)(messages);
103
+ messagesRef.current = messages;
104
+ const historyRequestRef = (0, import_react.useRef)(false);
105
+ const historyRequestIdRef = (0, import_react.useRef)(0);
106
+ const historyRequestControllerRef = (0, import_react.useRef)(null);
107
+ const historyRefreshRef = (0, import_react.useRef)(false);
108
+ const historyRefreshIdRef = (0, import_react.useRef)(0);
109
+ const historyRefreshControllerRef = (0, import_react.useRef)(null);
110
+ const prependAnchorRef = (0, import_react.useRef)(null);
111
+ const skipNextAutoScrollRef = (0, import_react.useRef)(false);
112
+ const prependExpiryRef = (0, import_react.useRef)(null);
113
+ const loadMoreHistory = (0, import_react.useCallback)(() => {
114
+ var _a;
115
+ const pagination = historyRef.current;
116
+ const el = listRef.current;
117
+ if (!(pagination == null ? void 0 : pagination.hasMore) || pagination.loading || historyRequestRef.current || !el)
118
+ return;
119
+ const direction = pagination.direction ?? "top";
120
+ if (direction === "top") {
121
+ if (prependExpiryRef.current)
122
+ clearTimeout(prependExpiryRef.current);
123
+ const currentMessages = messagesRef.current;
124
+ prependAnchorRef.current = {
125
+ sessionId: prevSessionIdRef.current,
126
+ firstMessageId: (_a = currentMessages[0]) == null ? void 0 : _a.id,
127
+ messageCount: currentMessages.length,
128
+ scrollTop: el.scrollTop,
129
+ scrollHeight: el.scrollHeight
130
+ };
131
+ }
132
+ historyRequestRef.current = true;
133
+ const requestId = ++historyRequestIdRef.current;
134
+ const controller = new AbortController();
135
+ historyRequestControllerRef.current = controller;
136
+ void Promise.resolve().then(() => pagination.onLoadMore({ signal: controller.signal })).catch(() => {
137
+ if (requestId !== historyRequestIdRef.current || controller.signal.aborted)
138
+ return;
139
+ prependAnchorRef.current = null;
140
+ import_antd.message.error("加载历史消息失败,请重试");
141
+ }).finally(() => {
142
+ if (requestId === historyRequestIdRef.current) {
143
+ historyRequestRef.current = false;
144
+ historyRequestControllerRef.current = null;
145
+ prependExpiryRef.current = setTimeout(() => {
146
+ prependAnchorRef.current = null;
147
+ prependExpiryRef.current = null;
148
+ }, 500);
149
+ }
150
+ });
151
+ }, []);
152
+ const refreshHistory = (0, import_react.useCallback)(() => {
153
+ const pagination = historyRef.current;
154
+ if (!(pagination == null ? void 0 : pagination.onRefresh) || pagination.refreshing || historyRefreshRef.current)
155
+ return;
156
+ historyRefreshRef.current = true;
157
+ const requestId = ++historyRefreshIdRef.current;
158
+ const controller = new AbortController();
159
+ historyRefreshControllerRef.current = controller;
160
+ void Promise.resolve().then(() => {
161
+ var _a;
162
+ return (_a = pagination.onRefresh) == null ? void 0 : _a.call(pagination, { signal: controller.signal });
163
+ }).catch(() => {
164
+ if (!controller.signal.aborted)
165
+ import_antd.message.error("刷新历史消息失败,请重试");
166
+ }).finally(() => {
167
+ if (requestId === historyRefreshIdRef.current) {
168
+ historyRefreshRef.current = false;
169
+ historyRefreshControllerRef.current = null;
170
+ }
171
+ });
172
+ }, []);
173
+ (0, import_react.useLayoutEffect)(() => {
174
+ var _a;
175
+ const anchor = prependAnchorRef.current;
176
+ const el = listRef.current;
177
+ if (!anchor || !el)
178
+ return;
179
+ if (anchor.sessionId !== sessionId) {
180
+ prependAnchorRef.current = null;
181
+ return;
182
+ }
183
+ if (messages.length <= anchor.messageCount || ((_a = messages[0]) == null ? void 0 : _a.id) === anchor.firstMessageId)
184
+ return;
185
+ el.scrollTop = anchor.scrollTop + el.scrollHeight - anchor.scrollHeight;
186
+ skipNextAutoScrollRef.current = true;
187
+ prependAnchorRef.current = null;
188
+ if (prependExpiryRef.current)
189
+ clearTimeout(prependExpiryRef.current);
190
+ prependExpiryRef.current = null;
191
+ }, [messages, sessionId]);
93
192
  const scrollToBottom = (0, import_react.useCallback)((behavior = "auto") => {
94
193
  var _a;
95
194
  (_a = messagesEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior });
96
195
  }, []);
97
- (0, import_react.useImperativeHandle)(ref, () => ({ scrollToBottom }), [scrollToBottom]);
196
+ const getScrollContainer = (0, import_react.useCallback)(() => listRef.current, []);
197
+ const getMessagePosition = (0, import_react.useCallback)((messageId) => {
198
+ const list = listRef.current;
199
+ if (!list)
200
+ return null;
201
+ const group = Array.from(list.children).find(
202
+ (element) => element instanceof HTMLElement && element.dataset.messageId === messageId
203
+ );
204
+ if (!group)
205
+ return null;
206
+ return group.getBoundingClientRect().top - list.getBoundingClientRect().top + list.scrollTop;
207
+ }, []);
208
+ const scrollToMessage = (0, import_react.useCallback)(
209
+ (messageId, behavior = "smooth") => {
210
+ const list = listRef.current;
211
+ const top = getMessagePosition(messageId);
212
+ if (list && top !== null)
213
+ list.scrollTo({ top, behavior });
214
+ },
215
+ [getMessagePosition]
216
+ );
217
+ (0, import_react.useImperativeHandle)(
218
+ ref,
219
+ () => ({ scrollToBottom, getScrollContainer, getMessagePosition, scrollToMessage }),
220
+ [scrollToBottom, getScrollContainer, getMessagePosition, scrollToMessage]
221
+ );
98
222
  const mergedStrategies = (0, import_react.useMemo)(
99
223
  () => (0, import_runtime.mergeChatStrategies)(preset, strategies),
100
224
  [preset, strategies]
@@ -110,7 +234,7 @@ var XAdkChatbot = (0, import_react.forwardRef)(
110
234
  },
111
235
  [toolKindResolver, mergedStrategies]
112
236
  );
113
- const parseProcessMessage = mergedStrategies.parseProcessMessage ?? import_utils.parseAgentMessage;
237
+ const parseProcessMessage = mergedStrategies.parseProcessMessage ?? import_utils2.parseAgentMessage;
114
238
  const resourceLinkSchemes = mergedStrategies.markdownResourceLinkSchemes;
115
239
  (0, import_react.useEffect)(() => {
116
240
  if (!initialized)
@@ -149,6 +273,7 @@ var XAdkChatbot = (0, import_react.forwardRef)(
149
273
  };
150
274
  }, [initialized, messages]);
151
275
  (0, import_react.useEffect)(() => {
276
+ var _a, _b;
152
277
  if (sessionId === void 0)
153
278
  return;
154
279
  if (prevSessionIdRef.current === sessionId)
@@ -156,10 +281,31 @@ var XAdkChatbot = (0, import_react.forwardRef)(
156
281
  prevSessionIdRef.current = sessionId;
157
282
  prevInitializedRef.current = false;
158
283
  userHasScrolledRef.current = false;
284
+ (_a = historyRequestControllerRef.current) == null ? void 0 : _a.abort();
285
+ (_b = historyRefreshControllerRef.current) == null ? void 0 : _b.abort();
286
+ prependAnchorRef.current = null;
287
+ historyRequestRef.current = false;
288
+ historyRequestIdRef.current += 1;
289
+ historyRefreshRef.current = false;
290
+ historyRefreshIdRef.current += 1;
291
+ if (prependExpiryRef.current)
292
+ clearTimeout(prependExpiryRef.current);
293
+ prependExpiryRef.current = null;
159
294
  }, [sessionId]);
295
+ (0, import_react.useEffect)(() => () => {
296
+ var _a, _b;
297
+ (_a = historyRequestControllerRef.current) == null ? void 0 : _a.abort();
298
+ (_b = historyRefreshControllerRef.current) == null ? void 0 : _b.abort();
299
+ if (prependExpiryRef.current)
300
+ clearTimeout(prependExpiryRef.current);
301
+ }, []);
160
302
  (0, import_react.useEffect)(() => {
161
303
  const previousCount = previousMessageCountRef.current;
162
304
  previousMessageCountRef.current = messages.length;
305
+ if (skipNextAutoScrollRef.current || prependAnchorRef.current) {
306
+ skipNextAutoScrollRef.current = false;
307
+ return;
308
+ }
163
309
  const hasNewUserMessage = messages.slice(previousCount).some((message) => message.role === "user");
164
310
  if (hasNewUserMessage) {
165
311
  userHasScrolledRef.current = false;
@@ -203,8 +349,15 @@ var XAdkChatbot = (0, import_react.forwardRef)(
203
349
  if (isAtBottom) {
204
350
  userHasScrolledRef.current = false;
205
351
  }
352
+ const pagination = historyRef.current;
353
+ if (pagination == null ? void 0 : pagination.hasMore) {
354
+ const threshold = pagination.threshold ?? 80;
355
+ const atLoadEdge = (pagination.direction ?? "top") === "top" ? currentTop <= threshold : el.scrollHeight - currentTop - el.clientHeight <= threshold;
356
+ if (atLoadEdge)
357
+ loadMoreHistory();
358
+ }
206
359
  lastScrollTopRef.current = currentTop;
207
- }, []);
360
+ }, [loadMoreHistory]);
208
361
  (0, import_react.useEffect)(() => {
209
362
  const listElement = listRef.current;
210
363
  if (!listElement)
@@ -214,6 +367,13 @@ var XAdkChatbot = (0, import_react.forwardRef)(
214
367
  listElement.removeEventListener("scroll", handleScroll);
215
368
  };
216
369
  }, [handleScroll]);
370
+ (0, import_react.useEffect)(() => {
371
+ if (!initialized || !(history == null ? void 0 : history.hasMore) || history.loading)
372
+ return;
373
+ const el = listRef.current;
374
+ if (el && el.scrollHeight <= el.clientHeight + 1)
375
+ loadMoreHistory();
376
+ }, [history == null ? void 0 : history.hasMore, history == null ? void 0 : history.loading, initialized, loadMoreHistory, messages]);
217
377
  const chatGroups = (0, import_react.useMemo)(() => {
218
378
  if (!enableGrouping) {
219
379
  return messages.map((msg) => ({
@@ -260,10 +420,11 @@ var XAdkChatbot = (0, import_react.forwardRef)(
260
420
  }, [messages, enableGrouping]);
261
421
  const renderBotGroup = (0, import_react.useCallback)(
262
422
  (group, isLastGroup, renderFunctionCall2) => {
423
+ var _a, _b, _c, _d, _e, _f, _g, _h;
263
424
  const { msgs, allFiles } = group;
264
425
  if (!enableProcessParsing) {
265
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.botMsg, children: msgs.map((msg, i) => {
266
- var _a;
426
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.botMsg, "data-message-id": group.id, children: msgs.map((msg, i) => {
427
+ var _a2;
267
428
  if (msg.text) {
268
429
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
269
430
  import_MarkdownRender.default,
@@ -285,7 +446,7 @@ var XAdkChatbot = (0, import_react.forwardRef)(
285
446
  msg,
286
447
  showDetail: showFnCallDetail,
287
448
  onConfirm,
288
- kind: resolveToolKind((_a = msg.functionCall) == null ? void 0 : _a.name, msg),
449
+ kind: resolveToolKind((_a2 = msg.functionCall) == null ? void 0 : _a2.name, msg),
289
450
  renderApproval: mergedStrategies.renderApproval,
290
451
  renderHandoff: mergedStrategies.renderHandoff
291
452
  },
@@ -397,24 +558,45 @@ var XAdkChatbot = (0, import_react.forwardRef)(
397
558
  flushProcessItems();
398
559
  const fullTextToCopy = msgs.filter((m) => !m.functionCall && !m.functionResponse).map((m) => m.text || "").join("");
399
560
  const lastBotMsg = msgs[msgs.length - 1];
400
- const hasProcess = nodes.some((n) => n.type === "process");
401
561
  const isGroupLoading = loading && isLastGroup;
402
562
  const actionProps = { message: group, isLastBotMsg: isLastGroup };
403
563
  const actionExtraNode = actionsExtra == null ? void 0 : actionsExtra(actionProps);
564
+ const firstProcessIdx = nodes.findIndex((n) => n.type === "process");
404
565
  const lastProcessIdx = nodes.findLastIndex((n) => n.type === "process");
405
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.botMsg, children: [
566
+ const processItems = nodes.slice(firstProcessIdx, lastProcessIdx + 1).flatMap(
567
+ (node) => node.type === "process" ? node.items : [
568
+ {
569
+ type: "text",
570
+ key: node.key,
571
+ title: "过程分析",
572
+ content: node.content
573
+ }
574
+ ]
575
+ );
576
+ const activeItem = processItems[processItems.length - 1];
577
+ const activeStep = (activeItem == null ? void 0 : activeItem.type) === "tool" ? String(
578
+ ((_c = (_b = (_a = activeItem.msg) == null ? void 0 : _a.functionCall) == null ? void 0 : _b.args) == null ? void 0 : _c.agentName) || ((_f = (_e = (_d = activeItem.msg) == null ? void 0 : _d.functionCall) == null ? void 0 : _e.args) == null ? void 0 : _f.componentName) || ((_h = (_g = activeItem.msg) == null ? void 0 : _g.functionCall) == null ? void 0 : _h.name) || ""
579
+ ) : typeof (activeItem == null ? void 0 : activeItem.title) === "string" ? activeItem.title : "";
580
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.botMsg, "data-message-id": group.id, children: [
406
581
  nodes.map((node, idx) => {
582
+ if (node.type === "text" && idx > firstProcessIdx && idx < lastProcessIdx) {
583
+ return null;
584
+ }
407
585
  if (node.type === "process") {
408
- const isLastProcess = idx === lastProcessIdx;
586
+ if (idx !== firstProcessIdx) {
587
+ return null;
588
+ }
409
589
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
410
590
  import_XAdkThoughtChain.default,
411
591
  {
412
- loading: isLastProcess && isGroupLoading,
413
- title: "思维链已完成",
414
- items: node.items,
592
+ collapsible: true,
593
+ loading: isGroupLoading,
594
+ title: "已完成",
595
+ activeStep,
596
+ items: processItems,
415
597
  showFnCallDetail,
416
598
  onConfirm,
417
- defaultOpen: isLastProcess && isGroupLoading,
599
+ defaultOpen: isGroupLoading,
418
600
  renderFunctionCall: renderFunctionCall2,
419
601
  toolKindResolver: (name) => resolveToolKind(name),
420
602
  strategies: mergedStrategies
@@ -502,43 +684,93 @@ var XAdkChatbot = (0, import_react.forwardRef)(
502
684
  ]
503
685
  );
504
686
  const renderUserGroup = (0, import_react.useCallback)(
505
- (group) => {
506
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.userMsg, children: group.msgs.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.userContainer, children: [
507
- m.fileData && m.fileData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: m.fileData.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
508
- import_FileGallery.default,
509
- {
510
- file,
511
- align: "left",
512
- style: { marginBottom: "16px" },
513
- onClick: onFileClick
514
- },
515
- index
516
- )) }),
517
- m.text && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
518
- "div",
519
- {
520
- className: styles.card,
521
- onCopy: (event) => {
522
- event.preventDefault();
523
- event.clipboardData.setData("text/plain", m.text || "");
524
- },
525
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
526
- import_MarkdownRender.default,
527
- {
528
- text: m.text,
529
- compact: true,
530
- bareUrlAsText: true,
531
- highlightPlainMentions: true,
532
- resourceLinkSchemes,
533
- onFileClick,
534
- onResourceLinkClick,
535
- renderResourceLink,
536
- markdownExtensions: mergedMarkdownExtensions
537
- }
538
- )
539
- }
540
- )
541
- ] }, m.id || i)) }, group.id);
687
+ (group, nextGroup) => {
688
+ var _a;
689
+ const compactWithNextText = group.msgs.some((message) => {
690
+ var _a2;
691
+ return Boolean((_a2 = message.fileData) == null ? void 0 : _a2.length);
692
+ }) && group.msgs.every((message) => {
693
+ var _a2;
694
+ return !((_a2 = message.text) == null ? void 0 : _a2.trim());
695
+ }) && (nextGroup == null ? void 0 : nextGroup.role) === "user" && nextGroup.msgs.some((message) => {
696
+ var _a2;
697
+ return Boolean((_a2 = message.text) == null ? void 0 : _a2.trim());
698
+ });
699
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
700
+ "div",
701
+ {
702
+ className: styles.userMsg,
703
+ "data-message-id": group.id,
704
+ style: compactWithNextText ? { marginBottom: 8 } : void 0,
705
+ children: [
706
+ group.msgs.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.userContainer, children: [
707
+ m.fileData && m.fileData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: m.fileData.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
708
+ import_FileGallery.default,
709
+ {
710
+ file,
711
+ align: "left",
712
+ style: {
713
+ marginBottom: compactWithNextText && i === group.msgs.length - 1 && index === m.fileData.length - 1 ? 0 : 16
714
+ },
715
+ onClick: onFileClick
716
+ },
717
+ index
718
+ )) }),
719
+ m.text && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
720
+ "div",
721
+ {
722
+ className: styles.card,
723
+ "data-xadk-user-card": true,
724
+ onCopy: (event) => {
725
+ event.preventDefault();
726
+ const selected = (0, import_utils.getSelectionText)(event.currentTarget);
727
+ event.clipboardData.setData(
728
+ "text/plain",
729
+ selected || m.text || ""
730
+ );
731
+ },
732
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
733
+ import_MarkdownRender.default,
734
+ {
735
+ text: m.text,
736
+ compact: true,
737
+ bareUrlAsText: true,
738
+ highlightPlainMentions: true,
739
+ resourceLinkSchemes,
740
+ onFileClick,
741
+ onResourceLinkClick,
742
+ renderResourceLink,
743
+ markdownExtensions: mergedMarkdownExtensions
744
+ }
745
+ )
746
+ }
747
+ )
748
+ ] }, m.id || i)),
749
+ showUserActions && group.msgs.some((message) => {
750
+ var _a2;
751
+ return Boolean((_a2 = message.text) == null ? void 0 : _a2.trim());
752
+ }) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `x-user-actions ${styles.userActions}`, children: (userActions == null ? void 0 : userActions({ message: group })) ?? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
753
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: styles.userTime, children: (0, import_utils.formatTimestamp)((_a = group.msgs[group.msgs.length - 1]) == null ? void 0 : _a.timestamp) }),
754
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: "复制内容", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
755
+ import_icons.CopyOutlined,
756
+ {
757
+ className: styles.userActionIcon,
758
+ onClick: () => {
759
+ const container = document.querySelector(
760
+ `[data-message-id="${group.id}"]`
761
+ );
762
+ const selected = (0, import_utils.getSelectionText)(container);
763
+ const fullText = group.msgs.map((message) => message.text || "").join("");
764
+ (0, import_copy_to_clipboard.default)(selected || fullText);
765
+ import_antd.message.success("复制成功");
766
+ }
767
+ }
768
+ ) })
769
+ ] }) })
770
+ ]
771
+ },
772
+ group.id
773
+ );
542
774
  },
543
775
  [
544
776
  styles,
@@ -546,7 +778,9 @@ var XAdkChatbot = (0, import_react.forwardRef)(
546
778
  onResourceLinkClick,
547
779
  renderResourceLink,
548
780
  mergedMarkdownExtensions,
549
- resourceLinkSchemes
781
+ resourceLinkSchemes,
782
+ showUserActions,
783
+ userActions
550
784
  ]
551
785
  );
552
786
  const renderSuggestions = () => {
@@ -576,6 +810,10 @@ var XAdkChatbot = (0, import_react.forwardRef)(
576
810
  ) }) }, item)) });
577
811
  };
578
812
  const isEmpty = messages.length === 0 && !prologue && (!suggestions || suggestions.length === 0);
813
+ const historyControls = history && (history.hasMore || history.loading || history.onRefresh) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.historyControls, children: [
814
+ history.onRefresh && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: refreshHistory, disabled: history.refreshing, children: history.refreshing ? "正在刷新..." : "刷新" }),
815
+ (history.hasMore || history.loading) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: loadMoreHistory, disabled: history.loading, children: history.loading ? "正在加载..." : "加载更多" })
816
+ ] });
579
817
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: (0, import_clsx.default)(styles.wrapper, className), style, children: [
580
818
  isEmpty && empty && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.emptyWrapper, children: typeof empty === "function" ? empty() : empty }),
581
819
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -585,6 +823,7 @@ var XAdkChatbot = (0, import_react.forwardRef)(
585
823
  ref: listRef,
586
824
  style: isEmpty ? { flex: 0 } : void 0,
587
825
  children: [
826
+ ((history == null ? void 0 : history.direction) ?? "top") === "top" && historyControls,
588
827
  prologue && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.prologue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
589
828
  import_MarkdownRender.default,
590
829
  {
@@ -596,13 +835,22 @@ var XAdkChatbot = (0, import_react.forwardRef)(
596
835
  markdownExtensions: mergedMarkdownExtensions
597
836
  }
598
837
  ) }),
599
- chatGroups.map(
600
- (group, idx) => group.role === "user" ? renderUserGroup(group) : renderBotGroup(
838
+ chatGroups.map((group, idx) => {
839
+ const context = {
601
840
  group,
602
- idx === chatGroups.length - 1,
603
- renderFunctionCall
604
- )
605
- ),
841
+ index: idx,
842
+ previousGroup: chatGroups[idx - 1],
843
+ nextGroup: chatGroups[idx + 1]
844
+ };
845
+ const defaultNode = group.role === "user" ? renderUserGroup(group, chatGroups[idx + 1]) : renderBotGroup(group, idx === chatGroups.length - 1, renderFunctionCall);
846
+ const customNode = renderGroup == null ? void 0 : renderGroup({ ...context, defaultNode });
847
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [
848
+ renderBeforeGroup == null ? void 0 : renderBeforeGroup(context),
849
+ customNode === void 0 ? defaultNode : customNode,
850
+ renderAfterGroup == null ? void 0 : renderAfterGroup(context)
851
+ ] }, group.id);
852
+ }),
853
+ (history == null ? void 0 : history.direction) === "bottom" && historyControls,
606
854
  renderSuggestions(),
607
855
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: messagesEndRef })
608
856
  ]