@ai-group/chat-sdk 3.8.0-alpha.1 → 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 (54) hide show
  1. package/dist/cjs/components/XAdkChatbot/index.js +240 -68
  2. package/dist/cjs/components/XAdkChatbot/index.js.map +3 -3
  3. package/dist/cjs/components/XAdkChatbot/styles.d.ts +1 -0
  4. package/dist/cjs/components/XAdkChatbot/styles.js +34 -6
  5. package/dist/cjs/components/XAdkChatbot/styles.js.map +2 -2
  6. package/dist/cjs/components/XAdkProvider/compound/Messages.d.ts +7 -1
  7. package/dist/cjs/components/XAdkProvider/compound/Messages.js +10 -0
  8. package/dist/cjs/components/XAdkProvider/compound/Messages.js.map +2 -2
  9. package/dist/cjs/components/XAdkSender/index.js +53 -5
  10. package/dist/cjs/components/XAdkSender/index.js.map +3 -3
  11. package/dist/cjs/components/XAdkThoughtChain/index.js +7 -3
  12. package/dist/cjs/components/XAdkThoughtChain/index.js.map +2 -2
  13. package/dist/cjs/components/XAdkThoughtChain/styles.d.ts +1 -1
  14. package/dist/cjs/components/XAdkThoughtChain/styles.js +25 -32
  15. package/dist/cjs/components/XAdkThoughtChain/styles.js.map +2 -2
  16. package/dist/cjs/components/XAiChatbot/index.js.map +2 -2
  17. package/dist/cjs/components/XAiProvider/index.js.map +2 -2
  18. package/dist/cjs/hooks/useADKMessageQueue.d.ts +4 -2
  19. package/dist/cjs/hooks/useADKMessageQueue.js +13 -11
  20. package/dist/cjs/hooks/useADKMessageQueue.js.map +2 -2
  21. package/dist/cjs/types/XAdkChatbot.d.ts +36 -0
  22. package/dist/cjs/types/XAdkChatbot.js.map +1 -1
  23. package/dist/cjs/types/XAdkSender.d.ts +8 -1
  24. package/dist/cjs/types/XAdkSender.js.map +1 -1
  25. package/dist/cjs/types/antdx.d.ts +4 -1
  26. package/dist/cjs/types/antdx.js.map +1 -1
  27. package/dist/esm/components/XAdkChatbot/index.js +210 -33
  28. package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
  29. package/dist/esm/components/XAdkChatbot/styles.d.ts +1 -0
  30. package/dist/esm/components/XAdkChatbot/styles.js +30 -29
  31. package/dist/esm/components/XAdkChatbot/styles.js.map +1 -1
  32. package/dist/esm/components/XAdkProvider/compound/Messages.d.ts +7 -1
  33. package/dist/esm/components/XAdkProvider/compound/Messages.js +11 -1
  34. package/dist/esm/components/XAdkProvider/compound/Messages.js.map +1 -1
  35. package/dist/esm/components/XAdkSender/index.js +80 -16
  36. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  37. package/dist/esm/components/XAdkThoughtChain/index.js +7 -7
  38. package/dist/esm/components/XAdkThoughtChain/index.js.map +1 -1
  39. package/dist/esm/components/XAdkThoughtChain/styles.d.ts +1 -1
  40. package/dist/esm/components/XAdkThoughtChain/styles.js +14 -14
  41. package/dist/esm/components/XAdkThoughtChain/styles.js.map +1 -1
  42. package/dist/esm/components/XAiChatbot/index.js.map +1 -1
  43. package/dist/esm/components/XAiProvider/index.js.map +1 -1
  44. package/dist/esm/hooks/useADKMessageQueue.d.ts +4 -2
  45. package/dist/esm/hooks/useADKMessageQueue.js +12 -10
  46. package/dist/esm/hooks/useADKMessageQueue.js.map +1 -1
  47. package/dist/esm/types/XAdkChatbot.d.ts +36 -0
  48. package/dist/esm/types/XAdkChatbot.js.map +1 -1
  49. package/dist/esm/types/XAdkSender.d.ts +8 -1
  50. package/dist/esm/types/XAdkSender.js.map +1 -1
  51. package/dist/esm/types/antdx.d.ts +4 -1
  52. package/dist/esm/types/antdx.js.map +1 -1
  53. package/dist/umd/chat-sdk.min.js +1 -1
  54. package/package.json +1 -1
@@ -54,6 +54,10 @@ var XAdkChatbot = (0, import_react.forwardRef)(
54
54
  prologue,
55
55
  suggestions,
56
56
  messages,
57
+ renderBeforeGroup,
58
+ renderAfterGroup,
59
+ renderGroup,
60
+ history,
57
61
  showFnCallDetail,
58
62
  onConfirm,
59
63
  onSuggest,
@@ -93,6 +97,98 @@ var XAdkChatbot = (0, import_react.forwardRef)(
93
97
  const prevInitializedRef = (0, import_react.useRef)(false);
94
98
  const prevSessionIdRef = (0, import_react.useRef)(sessionId);
95
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]);
96
192
  const scrollToBottom = (0, import_react.useCallback)((behavior = "auto") => {
97
193
  var _a;
98
194
  (_a = messagesEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior });
@@ -177,6 +273,7 @@ var XAdkChatbot = (0, import_react.forwardRef)(
177
273
  };
178
274
  }, [initialized, messages]);
179
275
  (0, import_react.useEffect)(() => {
276
+ var _a, _b;
180
277
  if (sessionId === void 0)
181
278
  return;
182
279
  if (prevSessionIdRef.current === sessionId)
@@ -184,10 +281,31 @@ var XAdkChatbot = (0, import_react.forwardRef)(
184
281
  prevSessionIdRef.current = sessionId;
185
282
  prevInitializedRef.current = false;
186
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;
187
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
+ }, []);
188
302
  (0, import_react.useEffect)(() => {
189
303
  const previousCount = previousMessageCountRef.current;
190
304
  previousMessageCountRef.current = messages.length;
305
+ if (skipNextAutoScrollRef.current || prependAnchorRef.current) {
306
+ skipNextAutoScrollRef.current = false;
307
+ return;
308
+ }
191
309
  const hasNewUserMessage = messages.slice(previousCount).some((message) => message.role === "user");
192
310
  if (hasNewUserMessage) {
193
311
  userHasScrolledRef.current = false;
@@ -231,8 +349,15 @@ var XAdkChatbot = (0, import_react.forwardRef)(
231
349
  if (isAtBottom) {
232
350
  userHasScrolledRef.current = false;
233
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
+ }
234
359
  lastScrollTopRef.current = currentTop;
235
- }, []);
360
+ }, [loadMoreHistory]);
236
361
  (0, import_react.useEffect)(() => {
237
362
  const listElement = listRef.current;
238
363
  if (!listElement)
@@ -242,6 +367,13 @@ var XAdkChatbot = (0, import_react.forwardRef)(
242
367
  listElement.removeEventListener("scroll", handleScroll);
243
368
  };
244
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]);
245
377
  const chatGroups = (0, import_react.useMemo)(() => {
246
378
  if (!enableGrouping) {
247
379
  return messages.map((msg) => ({
@@ -552,67 +684,93 @@ var XAdkChatbot = (0, import_react.forwardRef)(
552
684
  ]
553
685
  );
554
686
  const renderUserGroup = (0, import_react.useCallback)(
555
- (group) => {
556
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.userMsg, "data-message-id": group.id, children: group.msgs.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.userContainer, children: [
557
- 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)(
558
- import_FileGallery.default,
559
- {
560
- file,
561
- align: "left",
562
- style: { marginBottom: "16px" },
563
- onClick: onFileClick
564
- },
565
- index
566
- )) }),
567
- m.text && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
568
- "div",
569
- {
570
- className: styles.card,
571
- "data-xadk-user-card": true,
572
- onCopy: (event) => {
573
- event.preventDefault();
574
- const selected = (0, import_utils.getSelectionText)(event.currentTarget);
575
- event.clipboardData.setData(
576
- "text/plain",
577
- selected || m.text || ""
578
- );
579
- },
580
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
581
- import_MarkdownRender.default,
582
- {
583
- text: m.text,
584
- compact: true,
585
- bareUrlAsText: true,
586
- highlightPlainMentions: true,
587
- resourceLinkSchemes,
588
- onFileClick,
589
- onResourceLinkClick,
590
- renderResourceLink,
591
- markdownExtensions: mergedMarkdownExtensions
592
- }
593
- )
594
- }
595
- ),
596
- showUserActions && /* @__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: [
597
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: styles.userTime, children: (0, import_utils.formatTimestamp)(m.timestamp) }),
598
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: "复制内容", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
599
- import_icons.CopyOutlined,
600
- {
601
- className: styles.userActionIcon,
602
- onClick: () => {
603
- const card = document.querySelector(
604
- `[data-message-id="${group.id}"] [data-xadk-user-card]`
605
- );
606
- const selected = (0, import_utils.getSelectionText)(
607
- card
608
- );
609
- (0, import_copy_to_clipboard.default)(selected || m.text || "");
610
- import_antd.message.success("复制成功");
611
- }
612
- }
613
- ) })
614
- ] }) })
615
- ] }, 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
+ );
616
774
  },
617
775
  [
618
776
  styles,
@@ -652,6 +810,10 @@ var XAdkChatbot = (0, import_react.forwardRef)(
652
810
  ) }) }, item)) });
653
811
  };
654
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
+ ] });
655
817
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: (0, import_clsx.default)(styles.wrapper, className), style, children: [
656
818
  isEmpty && empty && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.emptyWrapper, children: typeof empty === "function" ? empty() : empty }),
657
819
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -661,6 +823,7 @@ var XAdkChatbot = (0, import_react.forwardRef)(
661
823
  ref: listRef,
662
824
  style: isEmpty ? { flex: 0 } : void 0,
663
825
  children: [
826
+ ((history == null ? void 0 : history.direction) ?? "top") === "top" && historyControls,
664
827
  prologue && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.prologue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
665
828
  import_MarkdownRender.default,
666
829
  {
@@ -672,13 +835,22 @@ var XAdkChatbot = (0, import_react.forwardRef)(
672
835
  markdownExtensions: mergedMarkdownExtensions
673
836
  }
674
837
  ) }),
675
- chatGroups.map(
676
- (group, idx) => group.role === "user" ? renderUserGroup(group) : renderBotGroup(
838
+ chatGroups.map((group, idx) => {
839
+ const context = {
677
840
  group,
678
- idx === chatGroups.length - 1,
679
- renderFunctionCall
680
- )
681
- ),
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,
682
854
  renderSuggestions(),
683
855
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: messagesEndRef })
684
856
  ]