@ant-design/agentic-ui 2.30.24 → 2.30.26

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 (57) hide show
  1. package/dist/Bubble/AIBubble.js +2 -3
  2. package/dist/Bubble/Bubble.js +3 -2
  3. package/dist/Bubble/List/index.js +130 -23
  4. package/dist/Bubble/MessagesContent/index.js +94 -74
  5. package/dist/Bubble/OpenAIMessageBubble/index.d.ts +6 -6
  6. package/dist/Bubble/OpenAIMessageBubble/index.js +3 -3
  7. package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.d.ts +1 -1
  8. package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.d.ts +1 -1
  9. package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.d.ts +1 -1
  10. package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.d.ts +1 -1
  11. package/dist/Bubble/OpenAIMessageBubble/types.d.ts +1 -1
  12. package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.d.ts +1 -1
  13. package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.d.ts +1 -1
  14. package/dist/Bubble/bubblePropsAreEqual.d.ts +23 -0
  15. package/dist/Bubble/bubblePropsAreEqual.js +272 -0
  16. package/dist/Components/TypingAnimation/index.d.ts +4 -1
  17. package/dist/Components/TypingAnimation/index.js +5 -3
  18. package/dist/MarkdownEditor/BaseMarkdownEditor.js +3 -2
  19. package/dist/MarkdownEditor/editor/elements/FootnoteDefinition/index.js +1 -2
  20. package/dist/MarkdownEditor/editor/elements/FootnoteReference/index.js +1 -2
  21. package/dist/MarkdownEditor/editor/elements/Head/index.js +1 -2
  22. package/dist/MarkdownEditor/editor/elements/LinkCard/index.js +1 -2
  23. package/dist/MarkdownEditor/editor/elements/Paragraph/ReadonlyParagraph.js +6 -3
  24. package/dist/MarkdownEditor/editor/elements/Paragraph/index.js +10 -30
  25. package/dist/MarkdownEditor/editor/elements/Table/EditableTable.js +1 -1
  26. package/dist/MarkdownEditor/editor/elements/index.js +1 -1
  27. package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.js +1 -1
  28. package/dist/MarkdownEditor/editor/plugins/withListsPlugin.js +5 -4
  29. package/dist/MarkdownEditor/editor/plugins/withMarkdown.js +1 -1
  30. package/dist/MarkdownEditor/editor/plugins/withSanitizeInvalidChildren.d.ts +2 -1
  31. package/dist/MarkdownEditor/editor/plugins/withSanitizeInvalidChildren.js +174 -30
  32. package/dist/MarkdownEditor/editor/store.d.ts +4 -3
  33. package/dist/MarkdownEditor/editor/store.js +5 -0
  34. package/dist/MarkdownEditor/editor/tools/InsertAutocomplete.js +1 -0
  35. package/dist/MarkdownEditor/style.js +0 -6
  36. package/dist/MarkdownInputField/MarkdownInputField.js +1 -1
  37. package/dist/MarkdownRenderer/MarkdownRenderer.js +2 -2
  38. package/dist/MarkdownRenderer/index.d.ts +2 -2
  39. package/dist/MarkdownRenderer/index.js +1 -1
  40. package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.d.ts +1 -1
  41. package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.js +15 -3
  42. package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.d.ts +2 -1
  43. package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +4 -4
  44. package/dist/Plugins/chart/BarChart/index.js +1 -1
  45. package/dist/Plugins/chart/ChartAttrToolBar/index.js +1 -1
  46. package/dist/Plugins/chart/index.d.ts +1 -1
  47. package/dist/Plugins/code/utils/index.d.ts +1 -1
  48. package/dist/Plugins/mermaid/MermaidRendererImpl.js +53 -419
  49. package/dist/Plugins/mermaid/index.js +1 -2
  50. package/dist/Plugins/mermaid/style.js +57 -59
  51. package/dist/Plugins/mermaid/utils.js +67 -8
  52. package/dist/Schema/SchemaForm/index.js +1 -1
  53. package/dist/Workspace/File/FileComponent.js +1 -1
  54. package/dist/Workspace/File/PreviewComponent.js +16 -2
  55. package/dist/Workspace/File/index.d.ts +1 -1
  56. package/dist/Workspace/File/index.js +2 -1
  57. package/package.json +2 -1
@@ -221,12 +221,11 @@ import { BubbleAvatar } from "./Avatar";
221
221
  import { BubbleBeforeNode } from "./BubbleBeforeNode";
222
222
  import { BubbleConfigContext } from "./BubbleConfigProvide";
223
223
  import { ContentFilemapView } from "./ContentFilemapView";
224
+ import { extractFilemapBlocks } from "./extractFilemapBlocks";
224
225
  import { BubbleFileView } from "./FileView";
225
- import { BubbleMessageDisplay } from "./MessagesContent";
226
+ import { BubbleMessageDisplay, LOADING_FLAT } from "./MessagesContent";
226
227
  import { MessagesContext } from "./MessagesContent/BubbleContext";
227
- import { LOADING_FLAT } from "./MessagesContent";
228
228
  import { BubbleExtra } from "./MessagesContent/BubbleExtra";
229
- import { extractFilemapBlocks } from "./extractFilemapBlocks";
230
229
  import { useStyle } from "./style";
231
230
  import { BubbleTitle } from "./Title";
232
231
  var AI_PLACEMENT = 'left';
@@ -54,6 +54,7 @@ import { memo, useMemo } from "react";
54
54
  import React from "react";
55
55
  import { debugInfo } from "../Utils/debugUtils";
56
56
  import { AIBubble } from "./AIBubble";
57
+ import { bubblePropsAreEqual } from "./bubblePropsAreEqual";
57
58
  import { useSchemaEditorBridge } from "./schema-editor";
58
59
  import { UserBubble } from "./UserBubble";
59
60
  /**
@@ -141,5 +142,5 @@ import { UserBubble } from "./UserBubble";
141
142
  return /*#__PURE__*/ React.createElement(AIBubble, _object_spread({}, bubbleProps, props.aIBubbleProps));
142
143
  };
143
144
  BubbleComponent.displayName = 'Bubble';
144
- // 使用 React.memo 优化性能,避免不必要的重新渲染
145
- export var Bubble = /*#__PURE__*/ memo(BubbleComponent);
145
+ // 自定义比较:列表侧常传入新的 styles / avatar 对象引用;扩展 props 时同步 bubblePropsAreEqual
146
+ export var Bubble = /*#__PURE__*/ memo(BubbleComponent, bubblePropsAreEqual);
@@ -60,6 +60,7 @@ import React from "react";
60
60
  import { LazyElement } from "../../MarkdownEditor/editor/components/LazyElement";
61
61
  import { Bubble } from "../Bubble";
62
62
  import { BubbleConfigContext } from "../BubbleConfigProvide";
63
+ import { shallowEqualRecord, shallowEqualStyles } from "../bubblePropsAreEqual";
63
64
  import { LOADING_FLAT } from "../MessagesContent";
64
65
  import { useStyle } from "./style";
65
66
  /**
@@ -166,17 +167,22 @@ import { useStyle } from "./style";
166
167
  var loadingKeyByIndexRef = useRef(new Map());
167
168
  // 真实 id 映射到稳定 key(过渡后沿用),避免同一条消息因 id 变化导致 remount
168
169
  var realIdToStableKeyRef = useRef(new Map());
170
+ /** 按列表行稳定 key 缓存合并后的 Bubble styles,避免每条消息每次父级渲染都换引用 */ var bubbleMergedStylesRef = useRef(new Map());
171
+ var bubbleMergedAvatarRef = useRef(new Map());
169
172
  var bubbleListDom = useMemo(function() {
170
173
  var _props_lazy;
171
174
  var isLazyEnabled = (_props_lazy = props.lazy) === null || _props_lazy === void 0 ? void 0 : _props_lazy.enable;
172
175
  var totalCount = bubbleList.length;
173
- return bubbleList.map(function(item, index) {
174
- var _props_bubbleRenderConfig;
176
+ var activeRowKeys = new Set();
177
+ var rows = bubbleList.map(function(item, index) {
178
+ var _ref;
179
+ var _props_lazy_shouldLazyLoad, _props_lazy, _props_bubbleRenderConfig;
175
180
  var isLast = bubbleList.length - 1 === index;
176
181
  var placement = item.role === 'user' ? 'right' : 'left';
177
- // 保持向后兼容性,设置isLatest
178
- item.isLatest = isLast;
179
- item.isLast = isLast;
182
+ var originDataWithFlags = _object_spread_props(_object_spread({}, item), {
183
+ isLatest: isLast,
184
+ isLast: isLast
185
+ });
180
186
  var itemKey;
181
187
  if (item.id === LOADING_FLAT) {
182
188
  var cacheKey = "".concat(index, "-").concat(item.createAt || Date.now());
@@ -198,14 +204,41 @@ import { useStyle } from "./style";
198
204
  itemKey = realId;
199
205
  }
200
206
  }
201
- var bubbleElement = /*#__PURE__*/ React.createElement(Bubble, {
207
+ activeRowKeys.add(itemKey);
208
+ var candidateAvatar = _object_spread({}, item.role === 'user' ? userMeta : assistantMeta, item.meta);
209
+ var prevAvatar = bubbleMergedAvatarRef.current.get(itemKey);
210
+ if (!prevAvatar || !shallowEqualRecord(prevAvatar, candidateAvatar)) {
211
+ bubbleMergedAvatarRef.current.set(itemKey, candidateAvatar);
212
+ }
213
+ var mergedAvatar = bubbleMergedAvatarRef.current.get(itemKey);
214
+ var candidateStyles = _object_spread_props(_object_spread({}, styles), {
215
+ bubbleListItemContentStyle: _object_spread({}, styles === null || styles === void 0 ? void 0 : styles.bubbleListItemContentStyle, placement === 'right' ? styles === null || styles === void 0 ? void 0 : styles.bubbleListRightItemContentStyle : styles === null || styles === void 0 ? void 0 : styles.bubbleListLeftItemContentStyle)
216
+ });
217
+ var prevMergedStyles = bubbleMergedStylesRef.current.get(itemKey);
218
+ if (!prevMergedStyles || !shallowEqualStyles(prevMergedStyles, candidateStyles)) {
219
+ bubbleMergedStylesRef.current.set(itemKey, candidateStyles);
220
+ }
221
+ var mergedStyles = bubbleMergedStylesRef.current.get(itemKey);
222
+ // LazyElement 依赖被观察元素的几何尺寸;display:contents 不产生盒子,会导致
223
+ // IntersectionObserver 在部分环境下永不触发,气泡永远不渲染。
224
+ var useLazyWrapper = !!isLazyEnabled && ((_ref = (_props_lazy = props.lazy) === null || _props_lazy === void 0 ? void 0 : (_props_lazy_shouldLazyLoad = _props_lazy.shouldLazyLoad) === null || _props_lazy_shouldLazyLoad === void 0 ? void 0 : _props_lazy_shouldLazyLoad.call(_props_lazy, index, totalCount)) !== null && _ref !== void 0 ? _ref : true);
225
+ var bubbleElement = /*#__PURE__*/ React.createElement("div", {
202
226
  key: itemKey,
227
+ style: useLazyWrapper ? {
228
+ minWidth: 0,
229
+ width: '100%'
230
+ } : {
231
+ display: 'contents'
232
+ },
233
+ "data-bubble-list-item": true,
234
+ "data-is-last": isLast ? 'true' : 'false'
235
+ }, /*#__PURE__*/ React.createElement(Bubble, {
203
236
  "data-id": item.id,
204
- avatar: _object_spread({}, item.role === 'user' ? userMeta : assistantMeta, item.meta),
237
+ avatar: mergedAvatar,
205
238
  preMessage: bubbleList[index - 1],
206
239
  id: item.id,
207
240
  style: _object_spread({}, styles === null || styles === void 0 ? void 0 : styles.bubbleListItemStyle),
208
- originData: item,
241
+ originData: originDataWithFlags,
209
242
  placement: placement,
210
243
  time: item.updateAt || item.createAt,
211
244
  deps: deps,
@@ -216,9 +249,7 @@ import { useStyle } from "./style";
216
249
  bubbleRef: props.bubbleRef,
217
250
  markdownRenderConfig: markdownRenderConfig,
218
251
  docListProps: props.docListProps,
219
- styles: _object_spread_props(_object_spread({}, styles), {
220
- bubbleListItemContentStyle: _object_spread({}, styles === null || styles === void 0 ? void 0 : styles.bubbleListItemContentStyle, placement === 'right' ? styles === null || styles === void 0 ? void 0 : styles.bubbleListRightItemContentStyle : styles === null || styles === void 0 ? void 0 : styles.bubbleListLeftItemContentStyle)
221
- }),
252
+ styles: mergedStyles,
222
253
  readonly: props.readonly,
223
254
  onReply: props.onReply,
224
255
  onDisLike: props.onDisLike,
@@ -231,19 +262,73 @@ import { useStyle } from "./style";
231
262
  customConfig: props === null || props === void 0 ? void 0 : (_props_bubbleRenderConfig = props.bubbleRenderConfig) === null || _props_bubbleRenderConfig === void 0 ? void 0 : _props_bubbleRenderConfig.customConfig,
232
263
  shouldShowCopy: props.shouldShowCopy,
233
264
  shouldShowVoice: props.shouldShowVoice
234
- });
265
+ }));
266
+ return {
267
+ itemKey: itemKey,
268
+ bubbleElement: bubbleElement,
269
+ isLazyEnabled: isLazyEnabled,
270
+ index: index,
271
+ item: item,
272
+ totalCount: totalCount,
273
+ useLazyWrapper: useLazyWrapper
274
+ };
275
+ });
276
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
277
+ try {
278
+ for(var _iterator = bubbleMergedStylesRef.current.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
279
+ var k = _step.value;
280
+ if (!activeRowKeys.has(k)) {
281
+ bubbleMergedStylesRef.current.delete(k);
282
+ }
283
+ }
284
+ } catch (err) {
285
+ _didIteratorError = true;
286
+ _iteratorError = err;
287
+ } finally{
288
+ try {
289
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
290
+ _iterator.return();
291
+ }
292
+ } finally{
293
+ if (_didIteratorError) {
294
+ throw _iteratorError;
295
+ }
296
+ }
297
+ }
298
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
299
+ try {
300
+ for(var _iterator1 = bubbleMergedAvatarRef.current.keys()[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
301
+ var k1 = _step1.value;
302
+ if (!activeRowKeys.has(k1)) {
303
+ bubbleMergedAvatarRef.current.delete(k1);
304
+ }
305
+ }
306
+ } catch (err) {
307
+ _didIteratorError1 = true;
308
+ _iteratorError1 = err;
309
+ } finally{
310
+ try {
311
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
312
+ _iterator1.return();
313
+ }
314
+ } finally{
315
+ if (_didIteratorError1) {
316
+ throw _iteratorError1;
317
+ }
318
+ }
319
+ }
320
+ return rows.map(function(param) {
321
+ var itemKey = param.itemKey, bubbleElement = param.bubbleElement, lazyOn = param.isLazyEnabled, index = param.index, item = param.item, count = param.totalCount, useLazyWrapper = param.useLazyWrapper;
235
322
  // 如果启用了懒加载,用 LazyElement 包裹
236
- if (isLazyEnabled) {
237
- var _ref, _ref1, _ref2;
238
- var _props_lazy_shouldLazyLoad, _props_lazy, _props_lazy1, _props_lazy2, _props_lazy3;
239
- // 检查是否应该对该消息启用懒加载
240
- var shouldLazyLoad = (_ref = (_props_lazy = props.lazy) === null || _props_lazy === void 0 ? void 0 : (_props_lazy_shouldLazyLoad = _props_lazy.shouldLazyLoad) === null || _props_lazy_shouldLazyLoad === void 0 ? void 0 : _props_lazy_shouldLazyLoad.call(_props_lazy, index, totalCount)) !== null && _ref !== void 0 ? _ref : true;
323
+ if (lazyOn) {
324
+ var _ref, _ref1;
325
+ var _props_lazy, _props_lazy1, _props_lazy2;
241
326
  // 如果不需要懒加载,直接返回元素
242
- if (!shouldLazyLoad) {
327
+ if (!useLazyWrapper) {
243
328
  return bubbleElement;
244
329
  }
245
330
  // 创建适配的 renderPlaceholder,将 role 信息添加到 elementInfo
246
- var adaptedRenderPlaceholder = ((_props_lazy1 = props.lazy) === null || _props_lazy1 === void 0 ? void 0 : _props_lazy1.renderPlaceholder) ? function(lazyProps) {
331
+ var adaptedRenderPlaceholder = ((_props_lazy = props.lazy) === null || _props_lazy === void 0 ? void 0 : _props_lazy.renderPlaceholder) ? function(lazyProps) {
247
332
  return props.lazy.renderPlaceholder(_object_spread_props(_object_spread({}, lazyProps), {
248
333
  elementInfo: lazyProps.elementInfo ? _object_spread_props(_object_spread({}, lazyProps.elementInfo), {
249
334
  role: item.role
@@ -252,13 +337,13 @@ import { useStyle } from "./style";
252
337
  } : undefined;
253
338
  return /*#__PURE__*/ React.createElement(LazyElement, {
254
339
  key: itemKey,
255
- placeholderHeight: (_ref1 = (_props_lazy2 = props.lazy) === null || _props_lazy2 === void 0 ? void 0 : _props_lazy2.placeholderHeight) !== null && _ref1 !== void 0 ? _ref1 : 100,
256
- rootMargin: (_ref2 = (_props_lazy3 = props.lazy) === null || _props_lazy3 === void 0 ? void 0 : _props_lazy3.rootMargin) !== null && _ref2 !== void 0 ? _ref2 : '200px',
340
+ placeholderHeight: (_ref = (_props_lazy1 = props.lazy) === null || _props_lazy1 === void 0 ? void 0 : _props_lazy1.placeholderHeight) !== null && _ref !== void 0 ? _ref : 100,
341
+ rootMargin: (_ref1 = (_props_lazy2 = props.lazy) === null || _props_lazy2 === void 0 ? void 0 : _props_lazy2.rootMargin) !== null && _ref1 !== void 0 ? _ref1 : '200px',
257
342
  renderPlaceholder: adaptedRenderPlaceholder,
258
343
  elementInfo: {
259
344
  type: 'bubble',
260
345
  index: index,
261
- total: totalCount
346
+ total: count
262
347
  }
263
348
  }, bubbleElement);
264
349
  }
@@ -266,8 +351,30 @@ import { useStyle } from "./style";
266
351
  });
267
352
  }, [
268
353
  bubbleList,
354
+ bubbleListRef,
355
+ bubbleRenderConfig,
356
+ classNames,
357
+ deps,
358
+ markdownRenderConfig,
359
+ props.bubbleRef,
360
+ props.docListProps,
361
+ props.lazy,
362
+ props.onAvatarClick,
363
+ props.onCancelLike,
364
+ props.onDisLike,
365
+ props.onDislike,
366
+ props.onDoubleClick,
367
+ props.onLike,
368
+ props.onLikeCancel,
369
+ props.onReply,
370
+ props.pure,
371
+ props.readonly,
372
+ props.shouldShowCopy,
373
+ props.shouldShowVoice,
269
374
  props.style,
270
- props.lazy
375
+ styles,
376
+ userMeta,
377
+ assistantMeta
271
378
  ]);
272
379
  if (loading) return wrapSSR(/*#__PURE__*/ React.createElement(BubbleConfigContext.Provider, {
273
380
  value: mergedContext
@@ -263,7 +263,7 @@ function _ts_generator(thisArg, body) {
263
263
  import { ExportOutlined } from "@ant-design/icons";
264
264
  import { ConfigProvider, Popover, Tooltip, Typography } from "antd";
265
265
  import classNames from "clsx";
266
- import React, { useContext, useMemo } from "react";
266
+ import React, { useCallback, useContext, useMemo } from "react";
267
267
  import { ActionIconBox } from "../../Components/ActionIconBox";
268
268
  import { I18nContext } from "../../I18n";
269
269
  import { MarkdownEditor, useRefFunction } from "../../index";
@@ -322,7 +322,7 @@ var THINKING_DOT_INDICES = [
322
322
  "readonly",
323
323
  "contentAfterDom"
324
324
  ]);
325
- var _props_originData, _props_originData1, _props_originData_extra, _props_originData2, _props_bubbleRenderConfig, _props_originData3, _props_bubbleRenderConfig1, _props_originData4, _props_originData5, _props_originData6, _props_originData7, _props_originData8, _props_bubbleRenderConfig2, _props_bubbleRenderConfig3;
325
+ var _props_originData, _props_originData1, _props_originData_extra, _props_originData2, _props_bubbleRenderConfig, _props_originData3, _props_bubbleRenderConfig1, _props_originData4, _props_originData_extra1, _props_originData5, _props_customConfig_PopoverProps, _props_customConfig, _props_customConfig_PopoverProps1, _props_customConfig1, _props_customConfig2, _props_markdownRenderConfig_fncProps, _props_markdownRenderConfig, _props_markdownRenderConfig1, _props_originData6, _props_originData7, _props_originData8, _props_originData9, _props_bubbleRenderConfig2, _props_bubbleRenderConfig3;
326
326
  /**
327
327
  * 获取聊天配置上下文
328
328
  * @type {ChatConfigContext}
@@ -340,6 +340,9 @@ var THINKING_DOT_INDICES = [
340
340
  });
341
341
  return node;
342
342
  });
343
+ var handleFootnoteDefinitionChange = useCallback(function(list) {
344
+ setNodeList(list);
345
+ }, []);
343
346
  var typing = useMemo(function() {
344
347
  var _props_originData, _props_originData1, _props_originData_extra, _props_originData2, _props_originData3;
345
348
  return ((_props_originData = props.originData) === null || _props_originData === void 0 ? void 0 : _props_originData.isAborted) !== true && ((_props_originData1 = props.originData) === null || _props_originData1 === void 0 ? void 0 : _props_originData1.isFinished) === false && (props === null || props === void 0 ? void 0 : (_props_originData2 = props.originData) === null || _props_originData2 === void 0 ? void 0 : (_props_originData_extra = _props_originData2.extra) === null || _props_originData_extra === void 0 ? void 0 : _props_originData_extra.isHistory) === undefined && ((_props_originData3 = props.originData) === null || _props_originData3 === void 0 ? void 0 : _props_originData3.isFinished) !== undefined;
@@ -369,8 +372,89 @@ var THINKING_DOT_INDICES = [
369
372
  (_props_originData4 = props.originData) === null || _props_originData4 === void 0 ? void 0 : _props_originData4.isLast,
370
373
  contentAfterDom
371
374
  ]);
375
+ var mdReferenceRender = useCallback(function(mdProps, _) {
376
+ var _props_originData_extra, _props_originData, _props_customConfig_PopoverProps, _props_customConfig, _props_customConfig1, _props_customConfig_PopoverProps1, _props_customConfig2, _item_origin_text;
377
+ var reference_url_info_list = ((_props_originData = props.originData) === null || _props_originData === void 0 ? void 0 : (_props_originData_extra = _props_originData.extra) === null || _props_originData_extra === void 0 ? void 0 : _props_originData_extra.reference_url_info_list) || [];
378
+ var item = reference_url_info_list.find(function(row) {
379
+ return row.placeholder === "[".concat(mdProps.children, "]") || row.placeholder === "[^".concat(mdProps.children, "]");
380
+ }) || funRender(mdProps);
381
+ if (!item) return;
382
+ if (!(item === null || item === void 0 ? void 0 : item.origin_text)) return null;
383
+ return /*#__PURE__*/ React.createElement(Popover, {
384
+ title: /*#__PURE__*/ React.createElement("div", {
385
+ className: classNames("".concat(baseChatCls, "-messages-content-popover-title"), hashId),
386
+ style: props === null || props === void 0 ? void 0 : (_props_customConfig = props.customConfig) === null || _props_customConfig === void 0 ? void 0 : (_props_customConfig_PopoverProps = _props_customConfig.PopoverProps) === null || _props_customConfig_PopoverProps === void 0 ? void 0 : _props_customConfig_PopoverProps.titleStyle
387
+ }, /*#__PURE__*/ React.createElement("div", null, (locale === null || locale === void 0 ? void 0 : locale['chat.message.referenceDocument']) || '参考文档'), (item === null || item === void 0 ? void 0 : item.origin_url) ? /*#__PURE__*/ React.createElement(ActionIconBox, {
388
+ title: (locale === null || locale === void 0 ? void 0 : locale['chat.message.viewOriginal']) || '查看原文',
389
+ tooltipProps: props === null || props === void 0 ? void 0 : (_props_customConfig1 = props.customConfig) === null || _props_customConfig1 === void 0 ? void 0 : _props_customConfig1.TooltipProps,
390
+ onClick: function onClick() {
391
+ var _props_markdownRenderConfig_fncProps, _props_markdownRenderConfig;
392
+ if ((_props_markdownRenderConfig = props.markdownRenderConfig) === null || _props_markdownRenderConfig === void 0 ? void 0 : (_props_markdownRenderConfig_fncProps = _props_markdownRenderConfig.fncProps) === null || _props_markdownRenderConfig_fncProps === void 0 ? void 0 : _props_markdownRenderConfig_fncProps.onOriginUrlClick) {
393
+ props.markdownRenderConfig.fncProps.onOriginUrlClick(item.origin_url);
394
+ return;
395
+ }
396
+ window.open(item.origin_url);
397
+ }
398
+ }, /*#__PURE__*/ React.createElement(ExportOutlined, null)) : null),
399
+ content: /*#__PURE__*/ React.createElement("div", {
400
+ className: classNames("".concat(baseChatCls, "-messages-content-popover-content"), hashId),
401
+ style: props === null || props === void 0 ? void 0 : (_props_customConfig2 = props.customConfig) === null || _props_customConfig2 === void 0 ? void 0 : (_props_customConfig_PopoverProps1 = _props_customConfig2.PopoverProps) === null || _props_customConfig_PopoverProps1 === void 0 ? void 0 : _props_customConfig_PopoverProps1.contentStyle
402
+ }, /*#__PURE__*/ React.createElement(MarkdownEditor, {
403
+ style: {
404
+ padding: 0,
405
+ width: '100%'
406
+ },
407
+ tableConfig: {
408
+ actions: {
409
+ fullScreen: 'modal'
410
+ }
411
+ },
412
+ readonly: true,
413
+ contentStyle: {
414
+ padding: 0,
415
+ width: '100%'
416
+ },
417
+ initValue: item === null || item === void 0 ? void 0 : (_item_origin_text = item.origin_text) === null || _item_origin_text === void 0 ? void 0 : _item_origin_text.trim()
418
+ }), (item === null || item === void 0 ? void 0 : item.docId) && item.doc_name ? /*#__PURE__*/ React.createElement(Tooltip, {
419
+ mouseEnterDelay: 0.3,
420
+ title: /*#__PURE__*/ React.createElement(Typography.Text, {
421
+ copyable: {
422
+ text: item.docId
423
+ }
424
+ }, item.docId)
425
+ }, /*#__PURE__*/ React.createElement("div", {
426
+ className: classNames("".concat(baseChatCls, "-messages-content-doc-tag"), hashId)
427
+ }, /*#__PURE__*/ React.createElement("img", {
428
+ className: classNames("".concat(baseChatCls, "-messages-content-doc-tag-icon"), hashId),
429
+ src: 'https://mdn.alipayobjects.com/huamei_ptjqan/afts/img/A*kF_GTppRbp4AAAAAAAAAAAAADkN6AQ/original'
430
+ }), /*#__PURE__*/ React.createElement("div", {
431
+ className: classNames("".concat(baseChatCls, "-messages-content-doc-name"), hashId)
432
+ }, item === null || item === void 0 ? void 0 : item.doc_name))) : null)
433
+ }, _);
434
+ }, [
435
+ (_props_originData5 = props.originData) === null || _props_originData5 === void 0 ? void 0 : (_props_originData_extra1 = _props_originData5.extra) === null || _props_originData_extra1 === void 0 ? void 0 : _props_originData_extra1.reference_url_info_list,
436
+ funRender,
437
+ locale,
438
+ baseChatCls,
439
+ hashId,
440
+ props === null || props === void 0 ? void 0 : (_props_customConfig = props.customConfig) === null || _props_customConfig === void 0 ? void 0 : (_props_customConfig_PopoverProps = _props_customConfig.PopoverProps) === null || _props_customConfig_PopoverProps === void 0 ? void 0 : _props_customConfig_PopoverProps.titleStyle,
441
+ props === null || props === void 0 ? void 0 : (_props_customConfig1 = props.customConfig) === null || _props_customConfig1 === void 0 ? void 0 : (_props_customConfig_PopoverProps1 = _props_customConfig1.PopoverProps) === null || _props_customConfig_PopoverProps1 === void 0 ? void 0 : _props_customConfig_PopoverProps1.contentStyle,
442
+ props === null || props === void 0 ? void 0 : (_props_customConfig2 = props.customConfig) === null || _props_customConfig2 === void 0 ? void 0 : _props_customConfig2.TooltipProps,
443
+ (_props_markdownRenderConfig = props.markdownRenderConfig) === null || _props_markdownRenderConfig === void 0 ? void 0 : (_props_markdownRenderConfig_fncProps = _props_markdownRenderConfig.fncProps) === null || _props_markdownRenderConfig_fncProps === void 0 ? void 0 : _props_markdownRenderConfig_fncProps.onOriginUrlClick
444
+ ]);
445
+ var markdownPreviewFncProps = useMemo(function() {
446
+ var _props_markdownRenderConfig;
447
+ return _object_spread({
448
+ render: mdReferenceRender,
449
+ onFootnoteDefinitionChange: handleFootnoteDefinitionChange
450
+ }, ((_props_markdownRenderConfig = props.markdownRenderConfig) === null || _props_markdownRenderConfig === void 0 ? void 0 : _props_markdownRenderConfig.fncProps) || {});
451
+ }, [
452
+ mdReferenceRender,
453
+ handleFootnoteDefinitionChange,
454
+ (_props_markdownRenderConfig1 = props.markdownRenderConfig) === null || _props_markdownRenderConfig1 === void 0 ? void 0 : _props_markdownRenderConfig1.fncProps
455
+ ]);
372
456
  var messageContent = useMemo(function() {
373
- var _props_originData, _props_bubbleRenderConfig, _props_bubbleRenderConfig1, _props_bubbleRenderConfig2, _props_bubbleRenderConfig3, _props_bubbleRenderConfig_extraRender, _props_bubbleRenderConfig4, _props_originData_extra_tags_includes, _props_originData_extra_tags, _props_originData_extra, _props_originData1, _props_originData2, _props_originData_extra1, _props_originData3, _props_originData_extra2, _props_originData4, _props_originData5, _props_originData_extra3, _props_originData6, _props_docListProps, _props_originData7, _props_markdownRenderConfig, _props_originData8, _props_originData_extra4, _props_originData9;
457
+ var _props_originData, _props_bubbleRenderConfig, _props_bubbleRenderConfig1, _props_bubbleRenderConfig2, _props_bubbleRenderConfig3, _props_bubbleRenderConfig_extraRender, _props_bubbleRenderConfig4, _props_originData_extra_tags_includes, _props_originData_extra_tags, _props_originData_extra, _props_originData1, _props_originData2, _props_originData_extra1, _props_originData3, _props_originData_extra2, _props_originData4, _props_originData5, _props_originData_extra3, _props_originData6, _props_docListProps, _props_originData7, _props_originData8, _props_originData_extra4, _props_originData9;
374
458
  if (content === LOADING_FLAT || !((_props_originData = props.originData) === null || _props_originData === void 0 ? void 0 : _props_originData.isFinished) && !content) {
375
459
  var _context_thoughtChain;
376
460
  if ((context === null || context === void 0 ? void 0 : (_context_thoughtChain = context.thoughtChain) === null || _context_thoughtChain === void 0 ? void 0 : _context_thoughtChain.alwaysRender) !== true) {
@@ -593,72 +677,7 @@ var THINKING_DOT_INDICES = [
593
677
  isFinished: (_props_originData7 = props.originData) === null || _props_originData7 === void 0 ? void 0 : _props_originData7.isFinished,
594
678
  beforeContent: beforeContent,
595
679
  afterContent: afterContent,
596
- fncProps: _object_spread({
597
- render: function render(mdProps, _) {
598
- var _props_originData_extra, _props_originData, _props_customConfig_PopoverProps, _props_customConfig, _props_customConfig1, _props_customConfig_PopoverProps1, _props_customConfig2, _item_origin_text;
599
- var reference_url_info_list = ((_props_originData = props.originData) === null || _props_originData === void 0 ? void 0 : (_props_originData_extra = _props_originData.extra) === null || _props_originData_extra === void 0 ? void 0 : _props_originData_extra.reference_url_info_list) || [];
600
- var item = reference_url_info_list.find(function(item) {
601
- return item.placeholder === "[".concat(mdProps.children, "]") || item.placeholder === "[^".concat(mdProps.children, "]");
602
- }) || funRender(mdProps);
603
- if (!item) return;
604
- if (!(item === null || item === void 0 ? void 0 : item.origin_text)) return null;
605
- return /*#__PURE__*/ React.createElement(Popover, {
606
- title: /*#__PURE__*/ React.createElement("div", {
607
- className: classNames("".concat(baseChatCls, "-messages-content-popover-title"), hashId),
608
- style: props === null || props === void 0 ? void 0 : (_props_customConfig = props.customConfig) === null || _props_customConfig === void 0 ? void 0 : (_props_customConfig_PopoverProps = _props_customConfig.PopoverProps) === null || _props_customConfig_PopoverProps === void 0 ? void 0 : _props_customConfig_PopoverProps.titleStyle
609
- }, /*#__PURE__*/ React.createElement("div", null, (locale === null || locale === void 0 ? void 0 : locale['chat.message.referenceDocument']) || '参考文档'), (item === null || item === void 0 ? void 0 : item.origin_url) ? /*#__PURE__*/ React.createElement(ActionIconBox, {
610
- title: (locale === null || locale === void 0 ? void 0 : locale['chat.message.viewOriginal']) || '查看原文',
611
- tooltipProps: props === null || props === void 0 ? void 0 : (_props_customConfig1 = props.customConfig) === null || _props_customConfig1 === void 0 ? void 0 : _props_customConfig1.TooltipProps,
612
- onClick: function onClick() {
613
- var _props_markdownRenderConfig_fncProps, _props_markdownRenderConfig;
614
- if ((_props_markdownRenderConfig = props.markdownRenderConfig) === null || _props_markdownRenderConfig === void 0 ? void 0 : (_props_markdownRenderConfig_fncProps = _props_markdownRenderConfig.fncProps) === null || _props_markdownRenderConfig_fncProps === void 0 ? void 0 : _props_markdownRenderConfig_fncProps.onOriginUrlClick) {
615
- var _props_markdownRenderConfig_fncProps1, _props_markdownRenderConfig1;
616
- (_props_markdownRenderConfig1 = props.markdownRenderConfig) === null || _props_markdownRenderConfig1 === void 0 ? void 0 : (_props_markdownRenderConfig_fncProps1 = _props_markdownRenderConfig1.fncProps) === null || _props_markdownRenderConfig_fncProps1 === void 0 ? void 0 : _props_markdownRenderConfig_fncProps1.onOriginUrlClick(item.origin_url);
617
- return;
618
- }
619
- window.open(item.origin_url);
620
- }
621
- }, /*#__PURE__*/ React.createElement(ExportOutlined, null)) : null),
622
- content: /*#__PURE__*/ React.createElement("div", {
623
- className: classNames("".concat(baseChatCls, "-messages-content-popover-content"), hashId),
624
- style: props === null || props === void 0 ? void 0 : (_props_customConfig2 = props.customConfig) === null || _props_customConfig2 === void 0 ? void 0 : (_props_customConfig_PopoverProps1 = _props_customConfig2.PopoverProps) === null || _props_customConfig_PopoverProps1 === void 0 ? void 0 : _props_customConfig_PopoverProps1.contentStyle
625
- }, /*#__PURE__*/ React.createElement(MarkdownEditor, {
626
- style: {
627
- padding: 0,
628
- width: '100%'
629
- },
630
- tableConfig: {
631
- actions: {
632
- fullScreen: 'modal'
633
- }
634
- },
635
- readonly: true,
636
- contentStyle: {
637
- padding: 0,
638
- width: '100%'
639
- },
640
- initValue: item === null || item === void 0 ? void 0 : (_item_origin_text = item.origin_text) === null || _item_origin_text === void 0 ? void 0 : _item_origin_text.trim()
641
- }), (item === null || item === void 0 ? void 0 : item.docId) && item.doc_name ? /*#__PURE__*/ React.createElement(Tooltip, {
642
- mouseEnterDelay: 0.3,
643
- title: /*#__PURE__*/ React.createElement(Typography.Text, {
644
- copyable: {
645
- text: item.docId
646
- }
647
- }, item.docId)
648
- }, /*#__PURE__*/ React.createElement("div", {
649
- className: classNames("".concat(baseChatCls, "-messages-content-doc-tag"), hashId)
650
- }, /*#__PURE__*/ React.createElement("img", {
651
- className: classNames("".concat(baseChatCls, "-messages-content-doc-tag-icon"), hashId),
652
- src: 'https://mdn.alipayobjects.com/huamei_ptjqan/afts/img/A*kF_GTppRbp4AAAAAAAAAAAAADkN6AQ/original'
653
- }), /*#__PURE__*/ React.createElement("div", {
654
- className: classNames("".concat(baseChatCls, "-messages-content-doc-name"), hashId)
655
- }, item === null || item === void 0 ? void 0 : item.doc_name))) : null)
656
- }, _);
657
- },
658
- onFootnoteDefinitionChange: function onFootnoteDefinitionChange(nodeList) {
659
- setNodeList(nodeList);
660
- }
661
- }, ((_props_markdownRenderConfig = props.markdownRenderConfig) === null || _props_markdownRenderConfig === void 0 ? void 0 : _props_markdownRenderConfig.fncProps) || {}),
680
+ fncProps: markdownPreviewFncProps,
662
681
  typing: typing,
663
682
  placement: props.placement,
664
683
  docListNode: docInfoDom,
@@ -669,14 +688,15 @@ var THINKING_DOT_INDICES = [
669
688
  }));
670
689
  }, [
671
690
  content,
672
- props === null || props === void 0 ? void 0 : (_props_originData5 = props.originData) === null || _props_originData5 === void 0 ? void 0 : _props_originData5.feedback,
673
- (_props_originData6 = props.originData) === null || _props_originData6 === void 0 ? void 0 : _props_originData6.isFinished,
674
- (_props_originData7 = props.originData) === null || _props_originData7 === void 0 ? void 0 : _props_originData7.isAborted,
675
- (_props_originData8 = props.originData) === null || _props_originData8 === void 0 ? void 0 : _props_originData8.isLast,
691
+ props === null || props === void 0 ? void 0 : (_props_originData6 = props.originData) === null || _props_originData6 === void 0 ? void 0 : _props_originData6.feedback,
692
+ (_props_originData7 = props.originData) === null || _props_originData7 === void 0 ? void 0 : _props_originData7.isFinished,
693
+ (_props_originData8 = props.originData) === null || _props_originData8 === void 0 ? void 0 : _props_originData8.isAborted,
694
+ (_props_originData9 = props.originData) === null || _props_originData9 === void 0 ? void 0 : _props_originData9.isLast,
676
695
  isExtraNull,
677
696
  props.deps,
678
697
  (_props_bubbleRenderConfig2 = props.bubbleRenderConfig) === null || _props_bubbleRenderConfig2 === void 0 ? void 0 : _props_bubbleRenderConfig2.beforeMessageRender,
679
- (_props_bubbleRenderConfig3 = props.bubbleRenderConfig) === null || _props_bubbleRenderConfig3 === void 0 ? void 0 : _props_bubbleRenderConfig3.afterMessageRender
698
+ (_props_bubbleRenderConfig3 = props.bubbleRenderConfig) === null || _props_bubbleRenderConfig3 === void 0 ? void 0 : _props_bubbleRenderConfig3.afterMessageRender,
699
+ markdownPreviewFncProps
680
700
  ]);
681
701
  return messageContent;
682
702
  };
@@ -1,11 +1,11 @@
1
+ export { mapOllamaMessagesToMessageBubbleData } from './mapOllamaMessages';
1
2
  export { mapOpenAIMessagesToMessageBubbleData } from './mapOpenAIMessages';
2
3
  export { mapOpenClawMessagesToMessageBubbleData } from './mapOpenClawMessages';
3
- export { mapOllamaMessagesToMessageBubbleData } from './mapOllamaMessages';
4
- export { normalizeOpenClawMessageToOpenAI, normalizeOpenClawMessagesToOpenAI, } from './normalizeOpenClawMessages';
5
4
  export { normalizeOllamaMessageToOpenAI, normalizeOllamaMessagesToOpenAI, } from './normalizeOllamaMessages';
5
+ export { normalizeOpenClawMessageToOpenAI, normalizeOpenClawMessagesToOpenAI, } from './normalizeOpenClawMessages';
6
+ export type { OllamaChatMessage, OllamaMessagesMapOptions, OllamaToolCall, } from './ollamaTypes';
7
+ export type { OpenClawChatMessage, OpenClawChatMessageToolResult, OpenClawChatMeta, OpenClawMessagesMapOptions, } from './openClawTypes';
8
+ export type { OpenAIChatContentPart, OpenAIChatContentPartFallback, OpenAIChatMessage, OpenAIChatMessageAssistant, OpenAIChatMessageFunction, OpenAIChatMessageSystem, OpenAIChatMessageTool, OpenAIChatMessageUser, OpenAIChatRefusalPart, OpenAIChatTextPart, OpenAIMessagesMapMessage, OpenAIMessagesMapOptions, } from './types';
9
+ export { useOllamaMessageBubbleData } from './useOllamaMessageBubbleData';
6
10
  export { useOpenAIMessageBubbleData } from './useOpenAIMessageBubbleData';
7
11
  export { useOpenClawMessageBubbleData } from './useOpenClawMessageBubbleData';
8
- export { useOllamaMessageBubbleData } from './useOllamaMessageBubbleData';
9
- export type { OpenAIChatContentPart, OpenAIChatContentPartFallback, OpenAIChatMessage, OpenAIChatMessageAssistant, OpenAIChatMessageFunction, OpenAIChatMessageSystem, OpenAIChatMessageTool, OpenAIChatMessageUser, OpenAIChatRefusalPart, OpenAIChatTextPart, OpenAIMessagesMapMessage, OpenAIMessagesMapOptions, } from './types';
10
- export type { OpenClawChatMessage, OpenClawChatMessageToolResult, OpenClawChatMeta, OpenClawMessagesMapOptions, } from './openClawTypes';
11
- export type { OllamaChatMessage, OllamaMessagesMapOptions, OllamaToolCall, } from './ollamaTypes';
@@ -1,8 +1,8 @@
1
+ export { mapOllamaMessagesToMessageBubbleData } from "./mapOllamaMessages";
1
2
  export { mapOpenAIMessagesToMessageBubbleData } from "./mapOpenAIMessages";
2
3
  export { mapOpenClawMessagesToMessageBubbleData } from "./mapOpenClawMessages";
3
- export { mapOllamaMessagesToMessageBubbleData } from "./mapOllamaMessages";
4
- export { normalizeOpenClawMessageToOpenAI, normalizeOpenClawMessagesToOpenAI } from "./normalizeOpenClawMessages";
5
4
  export { normalizeOllamaMessageToOpenAI, normalizeOllamaMessagesToOpenAI } from "./normalizeOllamaMessages";
5
+ export { normalizeOpenClawMessageToOpenAI, normalizeOpenClawMessagesToOpenAI } from "./normalizeOpenClawMessages";
6
+ export { useOllamaMessageBubbleData } from "./useOllamaMessageBubbleData";
6
7
  export { useOpenAIMessageBubbleData } from "./useOpenAIMessageBubbleData";
7
8
  export { useOpenClawMessageBubbleData } from "./useOpenClawMessageBubbleData";
8
- export { useOllamaMessageBubbleData } from "./useOllamaMessageBubbleData";
@@ -1,6 +1,6 @@
1
1
  import type { MessageBubbleData } from '../../Types/message';
2
- import type { OpenAIMessagesMapMessage } from './types';
3
2
  import type { OllamaChatMessage, OllamaMessagesMapOptions } from './ollamaTypes';
3
+ import type { OpenAIMessagesMapMessage } from './types';
4
4
  /**
5
5
  * 将 Ollama `/api/chat` 的 `messages` 转为 `MessageBubbleData[]`
6
6
  */
@@ -1,6 +1,6 @@
1
1
  import type { MessageBubbleData } from '../../Types/message';
2
- import type { OpenAIMessagesMapMessage } from './types';
3
2
  import type { OpenClawChatMessage, OpenClawMessagesMapOptions } from './openClawTypes';
3
+ import type { OpenAIMessagesMapMessage } from './types';
4
4
  /**
5
5
  * 将 OpenClaw 会话 / transcript 风格的 `messages` 转为 `MessageBubbleData[]`
6
6
  *(内部先归一化为 OpenAI 形状再复用 {@link mapOpenAIMessagesToMessageBubbleData})。
@@ -1,5 +1,5 @@
1
- import type { OpenAIChatMessage } from './types';
2
1
  import type { OllamaChatMessage } from './ollamaTypes';
2
+ import type { OpenAIChatMessage } from './types';
3
3
  /**
4
4
  * 将单条 Ollama `ChatMessage` 转为 {@link OpenAIChatMessage},供统一映射层使用。
5
5
  */
@@ -1,5 +1,5 @@
1
- import type { OpenAIChatMessage } from './types';
2
1
  import type { OpenClawChatMessage } from './openClawTypes';
2
+ import type { OpenAIChatMessage } from './types';
3
3
  /**
4
4
  * 将单条 OpenClaw 风格消息转为可与 {@link mapOpenAIMessagesToMessageBubbleData} 兼容的 OpenAI 形状(`toolResult` → `tool`)。
5
5
  */
@@ -1,5 +1,5 @@
1
- import type { MessageBubbleData } from '../../Types/message';
2
1
  import type { RoleType } from '../../Types/common';
2
+ import type { MessageBubbleData } from '../../Types/message';
3
3
  /**
4
4
  * OpenAI Chat Completions 风格的多段 content(与官方结构兼容,库内自建)
5
5
  */
@@ -1,6 +1,6 @@
1
1
  import type { MessageBubbleData } from '../../Types/message';
2
- import type { OpenAIMessagesMapMessage } from './types';
3
2
  import type { OllamaChatMessage, OllamaMessagesMapOptions } from './ollamaTypes';
3
+ import type { OpenAIMessagesMapMessage } from './types';
4
4
  /**
5
5
  * 将 Ollama `/api/chat` 的 messages 转为 MessageBubbleData[](与 {@link mapOllamaMessagesToMessageBubbleData} 一致,带 memo)。
6
6
  */
@@ -1,6 +1,6 @@
1
1
  import type { MessageBubbleData } from '../../Types/message';
2
- import type { OpenAIMessagesMapMessage } from './types';
3
2
  import type { OpenClawChatMessage, OpenClawMessagesMapOptions } from './openClawTypes';
3
+ import type { OpenAIMessagesMapMessage } from './types';
4
4
  /**
5
5
  * 将 OpenClaw 会话 / transcript 风格的 messages 转为 MessageBubbleData[](与 {@link mapOpenClawMessagesToMessageBubbleData} 一致,带 memo)。
6
6
  */
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Bubble 自定义 memo 比较(见 Bubble.tsx)。
3
+ *
4
+ * 维护约定:
5
+ * - 在 BubbleProps 上新增「会影响渲染」的字段时,必须在此补充比较逻辑,否则可能漏更新。
6
+ * - `markdownRenderConfig` / `bubbleRenderConfig` / `docListProps` / `customConfig`:按**顶层键**浅比较;
7
+ * 顶层值为普通对象时再浅比较一层;数组与函数仍按引用比较。父组件用 `useMemo` 稳定子对象引用更佳。
8
+ * - `originData`:按列出的标量与引用字段比较;`meta` 顶层浅比较;`meta.metadata` 再浅比较一层。
9
+ * 对 `extra` 等对象请勿原地 mutate,应替换引用,否则可能与 `extra !==` 不一致(若仅改嵌套且未换引用会漏更新)。
10
+ */
11
+ import type { BubbleProps } from './type';
12
+ export declare const shallowEqualRecord: (a: Record<string, unknown> | undefined | null, b: Record<string, unknown> | undefined | null) => boolean;
13
+ export declare const shallowEqualStyles: (a: BubbleProps['styles'] | undefined, b: BubbleProps['styles'] | undefined) => boolean;
14
+ /**
15
+ * Custom props comparator for Bubble memo.
16
+ * BubbleList (and callers) often pass fresh object references for styles / classNames / avatar
17
+ * while message data is unchanged; default shallow compare would still re-render every parent tick.
18
+ */
19
+ export declare const bubblePropsAreEqual: (prev: BubbleProps & {
20
+ deps?: unknown[];
21
+ }, next: BubbleProps & {
22
+ deps?: unknown[];
23
+ }) => boolean;