@ant-design/agentic-ui 2.30.4 → 2.30.6

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.
@@ -212,9 +212,10 @@ function _ts_generator(thisArg, body) {
212
212
  };
213
213
  }
214
214
  }
215
- import { memo, useContext } from "react";
215
+ import { memo, useContext, useRef } from "react";
216
216
  import { ConfigProvider, Flex } from "antd";
217
217
  import clsx from "clsx";
218
+ import { nanoid } from "nanoid";
218
219
  import React from "react";
219
220
  import { BubbleAvatar } from "./Avatar";
220
221
  import { BubbleBeforeNode } from "./BubbleBeforeNode";
@@ -222,6 +223,7 @@ import { BubbleConfigContext } from "./BubbleConfigProvide";
222
223
  import { BubbleFileView } from "./FileView";
223
224
  import { BubbleMessageDisplay } from "./MessagesContent";
224
225
  import { MessagesContext } from "./MessagesContent/BubbleContext";
226
+ import { LOADING_FLAT } from "./MessagesContent";
225
227
  import { BubbleExtra } from "./MessagesContent/BubbleExtra";
226
228
  import { useStyle } from "./style";
227
229
  import { BubbleTitle } from "./Title";
@@ -269,13 +271,14 @@ var getTaskList = function getTaskList(originData) {
269
271
  * </AIBubble>
270
272
  * ```
271
273
  */ export var AIBubble = /*#__PURE__*/ memo(function(props) {
272
- var _props_readonly;
274
+ var _ref, _messageDisplayKeyRef_current, _props_readonly;
273
275
  var _props_originData, _props_originData1, _props_originData2, _props_originData3, _props_originData4, _props_originData5, _props_bubbleRenderConfig, _props_originData_fileMap, _props_originData6, _props_bubbleRenderConfig1, _props_styles, _props_bubbleRenderConfig2, _bubbleRenderConfig_render;
274
276
  var onAvatarClick = props.onAvatarClick, className = props.className, style = props.style, bubbleRenderConfig = props.bubbleRenderConfig, classNames = props.classNames, styles = props.styles, originData = props.originData, preMessage = props.preMessage;
275
277
  var _React_useState = _sliced_to_array(React.useState(false), 2), hidePadding = _React_useState[0], setHidePadding = _React_useState[1];
278
+ var messageDisplayKeyRef = useRef(null);
276
279
  var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
277
280
  var context = useContext(BubbleConfigContext);
278
- var _ref = context || {}, compact = _ref.compact, standalone = _ref.standalone, extraShowOnHover = _ref.extraShowOnHover;
281
+ var _ref1 = context || {}, compact = _ref1.compact, standalone = _ref1.standalone, extraShowOnHover = _ref1.extraShowOnHover;
279
282
  var prefixClass = getPrefixCls('agentic');
280
283
  var _useStyle = useStyle(prefixClass), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
281
284
  var preMessageSameRole = isSameRoleAsPrevious(preMessage, originData);
@@ -300,14 +303,21 @@ var getTaskList = function getTaskList(originData) {
300
303
  prefixCls: "".concat(prefixClass, "-bubble-avatar"),
301
304
  style: styles === null || styles === void 0 ? void 0 : styles.bubbleListItemAvatarStyle
302
305
  }));
306
+ var id = props === null || props === void 0 ? void 0 : (_props_originData = props.originData) === null || _props_originData === void 0 ? void 0 : _props_originData.id;
307
+ if (id === undefined || id === LOADING_FLAT) {
308
+ if (!messageDisplayKeyRef.current) {
309
+ messageDisplayKeyRef.current = nanoid();
310
+ }
311
+ }
312
+ var messageDisplayKey = (_ref = (_messageDisplayKeyRef_current = messageDisplayKeyRef.current) !== null && _messageDisplayKeyRef_current !== void 0 ? _messageDisplayKeyRef_current : id) !== null && _ref !== void 0 ? _ref : nanoid();
303
313
  var messageContent = /*#__PURE__*/ React.createElement(BubbleMessageDisplay, {
304
314
  markdownRenderConfig: props.markdownRenderConfig,
305
315
  docListProps: props.docListProps,
306
316
  bubbleListRef: props.bubbleListRef,
307
317
  bubbleListItemExtraStyle: styles === null || styles === void 0 ? void 0 : styles.bubbleListItemExtraStyle,
308
318
  bubbleRef: props.bubbleRef,
309
- content: props === null || props === void 0 ? void 0 : (_props_originData = props.originData) === null || _props_originData === void 0 ? void 0 : _props_originData.content,
310
- key: props === null || props === void 0 ? void 0 : (_props_originData1 = props.originData) === null || _props_originData1 === void 0 ? void 0 : _props_originData1.id,
319
+ content: props === null || props === void 0 ? void 0 : (_props_originData1 = props.originData) === null || _props_originData1 === void 0 ? void 0 : _props_originData1.content,
320
+ key: messageDisplayKey,
311
321
  "data-id": props === null || props === void 0 ? void 0 : (_props_originData2 = props.originData) === null || _props_originData2 === void 0 ? void 0 : _props_originData2.id,
312
322
  avatar: props === null || props === void 0 ? void 0 : (_props_originData3 = props.originData) === null || _props_originData3 === void 0 ? void 0 : _props_originData3.meta,
313
323
  readonly: (_props_readonly = props.readonly) !== null && _props_readonly !== void 0 ? _props_readonly : false,
@@ -74,8 +74,9 @@ export var PureBubbleList = /*#__PURE__*/ React.memo(function(props) {
74
74
  }, [
75
75
  props.style
76
76
  ]);
77
- // 为 loading 项生成唯一的 key,使用 ref 缓存以确保稳定性
78
77
  var loadingKeysRef = useRef(new Map());
78
+ var loadingKeyByIndexRef = useRef(new Map());
79
+ var realIdToStableKeyRef = useRef(new Map());
79
80
  var listDom = useMemo(function() {
80
81
  var _props_lazy;
81
82
  var isLazyEnabled = (_props_lazy = props.lazy) === null || _props_lazy === void 0 ? void 0 : _props_lazy.enable;
@@ -88,15 +89,26 @@ export var PureBubbleList = /*#__PURE__*/ React.memo(function(props) {
88
89
  isLatest: isLast,
89
90
  isLast: isLast
90
91
  });
91
- // 如果 id 是 LOADING_FLAT,使用 uuid 作为 key
92
- // 使用 index 和 createAt 的组合作为缓存 key,确保同一项在重新渲染时保持相同的 key
93
- var itemKey = item.id;
92
+ var itemKey;
94
93
  if (item.id === LOADING_FLAT) {
95
94
  var cacheKey = "".concat(index, "-").concat(item.createAt || Date.now());
96
95
  if (!loadingKeysRef.current.has(cacheKey)) {
97
96
  loadingKeysRef.current.set(cacheKey, nanoid());
98
97
  }
99
98
  itemKey = loadingKeysRef.current.get(cacheKey);
99
+ loadingKeyByIndexRef.current.set(index, itemKey);
100
+ } else {
101
+ var realId = item.id;
102
+ var prevLoadingKey = loadingKeyByIndexRef.current.get(index);
103
+ if (prevLoadingKey) {
104
+ itemKey = prevLoadingKey;
105
+ realIdToStableKeyRef.current.set(realId, prevLoadingKey);
106
+ loadingKeyByIndexRef.current.delete(index);
107
+ } else if (realIdToStableKeyRef.current.has(realId)) {
108
+ itemKey = realIdToStableKeyRef.current.get(realId);
109
+ } else {
110
+ itemKey = realId;
111
+ }
100
112
  }
101
113
  var bubbleElement = /*#__PURE__*/ React.createElement(BubbleComponent, {
102
114
  key: itemKey,
@@ -161,8 +161,11 @@ import { useStyle } from "./style";
161
161
  JSON.stringify(props.style)
162
162
  ]);
163
163
  // 为 loading 项生成唯一的 key,使用 ref 缓存以确保稳定性
164
- // 使用 item 的唯一标识(index + createAt)作为缓存 key
165
164
  var loadingKeysRef = useRef(new Map());
165
+ // 记录每个 index 在上一轮是否是 loading,用于 loading→real 过渡时保持 key 稳定,避免闪动
166
+ var loadingKeyByIndexRef = useRef(new Map());
167
+ // 真实 id 映射到稳定 key(过渡后沿用),避免同一条消息因 id 变化导致 remount
168
+ var realIdToStableKeyRef = useRef(new Map());
166
169
  var bubbleListDom = useMemo(function() {
167
170
  var _props_lazy;
168
171
  var isLazyEnabled = (_props_lazy = props.lazy) === null || _props_lazy === void 0 ? void 0 : _props_lazy.enable;
@@ -174,15 +177,26 @@ import { useStyle } from "./style";
174
177
  // 保持向后兼容性,设置isLatest
175
178
  item.isLatest = isLast;
176
179
  item.isLast = isLast;
177
- // 如果 id 是 LOADING_FLAT,使用 uuid 作为 key
178
- // 使用 index 和 createAt 的组合作为缓存 key,确保同一项在重新渲染时保持相同的 key
179
- var itemKey = item.id;
180
+ var itemKey;
180
181
  if (item.id === LOADING_FLAT) {
181
182
  var cacheKey = "".concat(index, "-").concat(item.createAt || Date.now());
182
183
  if (!loadingKeysRef.current.has(cacheKey)) {
183
184
  loadingKeysRef.current.set(cacheKey, nanoid());
184
185
  }
185
186
  itemKey = loadingKeysRef.current.get(cacheKey);
187
+ loadingKeyByIndexRef.current.set(index, itemKey);
188
+ } else {
189
+ var realId = item.id;
190
+ var prevLoadingKey = loadingKeyByIndexRef.current.get(index);
191
+ if (prevLoadingKey) {
192
+ itemKey = prevLoadingKey;
193
+ realIdToStableKeyRef.current.set(realId, prevLoadingKey);
194
+ loadingKeyByIndexRef.current.delete(index);
195
+ } else if (realIdToStableKeyRef.current.has(realId)) {
196
+ itemKey = realIdToStableKeyRef.current.get(realId);
197
+ } else {
198
+ itemKey = realId;
199
+ }
186
200
  }
187
201
  var bubbleElement = /*#__PURE__*/ React.createElement(Bubble, {
188
202
  key: itemKey,
@@ -125,20 +125,22 @@ import { MessagesContext } from "./BubbleContext";
125
125
  var _content_includes, _htmlRef_current, _htmlRef_current1, _props_markdownRenderConfig, _props_originData, _props_originData1, _props_originData2, _props_markdownRenderConfig1, _props_markdownRenderConfig2, _props_markdownRenderConfig3;
126
126
  // MarkdownRenderer 渲染路径——轻量,不创建 Slate 实例
127
127
  if (renderMode === 'markdown') {
128
- var _props_originData3, _props_markdownRenderConfig4, _props_markdownRenderConfig5, _props_markdownRenderConfig6, _props_markdownRenderConfig7;
128
+ var _props_originData3, _props_markdownRenderConfig4, _props_markdownRenderConfig5, _props_markdownRenderConfig6, _props_markdownRenderConfig7, _props_markdownRenderConfig8, _props_markdownRenderConfig9;
129
129
  return /*#__PURE__*/ React.createElement(MarkdownRenderer, {
130
130
  content: content,
131
131
  streaming: typing,
132
132
  isFinished: (_props_originData3 = props.originData) === null || _props_originData3 === void 0 ? void 0 : _props_originData3.isFinished,
133
133
  plugins: (_props_markdownRenderConfig4 = props.markdownRenderConfig) === null || _props_markdownRenderConfig4 === void 0 ? void 0 : _props_markdownRenderConfig4.plugins,
134
+ queueOptions: (_props_markdownRenderConfig5 = props.markdownRenderConfig) === null || _props_markdownRenderConfig5 === void 0 ? void 0 : _props_markdownRenderConfig5.queueOptions,
135
+ streamingParagraphAnimation: (_props_markdownRenderConfig6 = props.markdownRenderConfig) === null || _props_markdownRenderConfig6 === void 0 ? void 0 : _props_markdownRenderConfig6.streamingParagraphAnimation,
134
136
  fncProps: fncProps,
135
137
  style: _object_spread({
136
138
  maxWidth: standalone ? '100%' : undefined,
137
139
  padding: isPaddingHidden ? 0 : undefined,
138
140
  margin: isPaddingHidden ? 0 : undefined
139
- }, ((_props_markdownRenderConfig5 = props.markdownRenderConfig) === null || _props_markdownRenderConfig5 === void 0 ? void 0 : _props_markdownRenderConfig5.style) || {}),
140
- codeProps: (_props_markdownRenderConfig6 = props.markdownRenderConfig) === null || _props_markdownRenderConfig6 === void 0 ? void 0 : _props_markdownRenderConfig6.codeProps,
141
- apaasify: (_props_markdownRenderConfig7 = props.markdownRenderConfig) === null || _props_markdownRenderConfig7 === void 0 ? void 0 : _props_markdownRenderConfig7.apaasify
141
+ }, ((_props_markdownRenderConfig7 = props.markdownRenderConfig) === null || _props_markdownRenderConfig7 === void 0 ? void 0 : _props_markdownRenderConfig7.style) || {}),
142
+ codeProps: (_props_markdownRenderConfig8 = props.markdownRenderConfig) === null || _props_markdownRenderConfig8 === void 0 ? void 0 : _props_markdownRenderConfig8.codeProps,
143
+ apaasify: (_props_markdownRenderConfig9 = props.markdownRenderConfig) === null || _props_markdownRenderConfig9 === void 0 ? void 0 : _props_markdownRenderConfig9.apaasify
142
144
  });
143
145
  }
144
146
  // Slate 渲染路径——保持向后兼容
@@ -4,7 +4,7 @@ import React from 'react';
4
4
  import { BaseEditor, Editor, Selection } from 'slate';
5
5
  import { HistoryEditor } from 'slate-history';
6
6
  import { ReactEditor, RenderElementProps } from 'slate-react';
7
- import type { RenderMode } from '../MarkdownRenderer/types';
7
+ import type { CharacterQueueOptions, RenderMode } from '../MarkdownRenderer/types';
8
8
  import { TagPopupProps } from './editor/elements/TagPopup';
9
9
  import { EditorStore } from './editor/store';
10
10
  import { InsertAutocompleteProps } from './editor/tools/InsertAutocomplete';
@@ -473,6 +473,16 @@ export type MarkdownEditorProps = {
473
473
  /** 自定义链接渲染函数 */
474
474
  onClick?: (url?: string) => boolean | void;
475
475
  };
476
+ /**
477
+ * MarkdownRenderer 字符队列(仅 `renderMode: 'markdown'` 只读预览时生效)
478
+ * @description 默认关闭逐字 RAF;需要打字机时再设 `{ animate: true, animateTailChars: 50 }` 等
479
+ */
480
+ queueOptions?: CharacterQueueOptions;
481
+ /**
482
+ * 流式 Markdown 末段淡入(仅 `renderMode: 'markdown'` 时传给 MarkdownRenderer)
483
+ * @description 默认 false;设为 true 时末段使用 AnimationText 入场,可能在高频更新时产生闪动
484
+ */
485
+ streamingParagraphAnimation?: boolean;
476
486
  /**
477
487
  * 依赖数组
478
488
  * @description 用于控制 MElement 组件是否刷新的依赖数组。当 deps 数组内容发生变化时,MElement 会重新渲染
@@ -4,6 +4,11 @@ export interface AnimationConfig {
4
4
  fadeDuration?: number;
5
5
  /** 缓动函数,默认 ease-out */
6
6
  easing?: string;
7
+ /**
8
+ * 已废弃:单段入场动画模式下不再按 chunk 瘦身 DOM,保留仅为类型兼容
9
+ * @deprecated
10
+ */
11
+ collapseThreshold?: number;
7
12
  }
8
13
  export interface AnimationTextProps {
9
14
  children: React.ReactNode;
@@ -12,8 +17,7 @@ export interface AnimationTextProps {
12
17
  /**
13
18
  * 流式文字淡入动画组件。
14
19
  *
15
- * 采用 opacity + translateY(GPU 硬件加速),清爽流派。
16
- * 动画结束后通过 animationend 标记 done,仍用 span 包裹以保持布局稳定。
20
+ * 同一段流式前缀追加(或尾部截断修正)只触发一次入场动画;非前缀替换时重播。
17
21
  */
18
22
  declare const AnimationText: React.NamedExoticComponent<AnimationTextProps>;
19
23
  export default AnimationText;
@@ -6,25 +6,6 @@ function _array_like_to_array(arr, len) {
6
6
  function _array_with_holes(arr) {
7
7
  if (Array.isArray(arr)) return arr;
8
8
  }
9
- function _array_without_holes(arr) {
10
- if (Array.isArray(arr)) return _array_like_to_array(arr);
11
- }
12
- function _define_property(obj, key, value) {
13
- if (key in obj) {
14
- Object.defineProperty(obj, key, {
15
- value: value,
16
- enumerable: true,
17
- configurable: true,
18
- writable: true
19
- });
20
- } else {
21
- obj[key] = value;
22
- }
23
- return obj;
24
- }
25
- function _iterable_to_array(iter) {
26
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
27
- }
28
9
  function _iterable_to_array_limit(arr, i) {
29
10
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
30
11
  if (_i == null) return;
@@ -52,54 +33,9 @@ function _iterable_to_array_limit(arr, i) {
52
33
  function _non_iterable_rest() {
53
34
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
54
35
  }
55
- function _non_iterable_spread() {
56
- throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
57
- }
58
- function _object_spread(target) {
59
- for(var i = 1; i < arguments.length; i++){
60
- var source = arguments[i] != null ? arguments[i] : {};
61
- var ownKeys = Object.keys(source);
62
- if (typeof Object.getOwnPropertySymbols === "function") {
63
- ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
64
- return Object.getOwnPropertyDescriptor(source, sym).enumerable;
65
- }));
66
- }
67
- ownKeys.forEach(function(key) {
68
- _define_property(target, key, source[key]);
69
- });
70
- }
71
- return target;
72
- }
73
- function ownKeys(object, enumerableOnly) {
74
- var keys = Object.keys(object);
75
- if (Object.getOwnPropertySymbols) {
76
- var symbols = Object.getOwnPropertySymbols(object);
77
- if (enumerableOnly) {
78
- symbols = symbols.filter(function(sym) {
79
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
80
- });
81
- }
82
- keys.push.apply(keys, symbols);
83
- }
84
- return keys;
85
- }
86
- function _object_spread_props(target, source) {
87
- source = source != null ? source : {};
88
- if (Object.getOwnPropertyDescriptors) {
89
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
90
- } else {
91
- ownKeys(Object(source)).forEach(function(key) {
92
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
93
- });
94
- }
95
- return target;
96
- }
97
36
  function _sliced_to_array(arr, i) {
98
37
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
99
38
  }
100
- function _to_consumable_array(arr) {
101
- return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
102
- }
103
39
  function _unsupported_iterable_to_array(o, minLen) {
104
40
  if (!o) return;
105
41
  if (typeof o === "string") return _array_like_to_array(o, minLen);
@@ -121,71 +57,43 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
121
57
  }
122
58
  return '';
123
59
  };
124
- /**
125
- * 识别 children 中是否包含 React 元素节点。
126
- * 富文本结构(链接、脚注、图片等)在纯文本差分下会丢失结构信息,直接透传更安全。
127
- */ var hasElementNode = function hasElementNode1(children) {
128
- if (children === null || children === undefined || typeof children === 'boolean') return false;
129
- if (typeof children === 'string' || typeof children === 'number') return false;
130
- if (Array.isArray(children)) return children.some(hasElementNode);
131
- return /*#__PURE__*/ React.isValidElement(children);
60
+ /** 流式同一段内:前后文案仅「前缀关系」变化(增长或尾部截断修正) */ var isStreamingCompatible = function isStreamingCompatible(prev, next) {
61
+ return prev.startsWith(next) || next.startsWith(prev);
132
62
  };
133
63
  /**
134
64
  * 流式文字淡入动画组件。
135
65
  *
136
- * 采用 opacity + translateY(GPU 硬件加速),清爽流派。
137
- * 动画结束后通过 animationend 标记 done,仍用 span 包裹以保持布局稳定。
66
+ * 同一段流式前缀追加(或尾部截断修正)只触发一次入场动画;非前缀替换时重播。
138
67
  */ var AnimationText = /*#__PURE__*/ React.memo(function(param) {
139
68
  var children = param.children, animationConfig = param.animationConfig;
140
- var _ref = animationConfig || {}, _ref_fadeDuration = _ref.fadeDuration, fadeDuration = _ref_fadeDuration === void 0 ? 200 : _ref_fadeDuration, _ref_easing = _ref.easing, easing = _ref_easing === void 0 ? 'ease-out' : _ref_easing;
141
- var _useState = _sliced_to_array(useState([]), 2), chunks = _useState[0], setChunks = _useState[1];
69
+ var _ref = animationConfig || {}, _ref_fadeDuration = _ref.fadeDuration, fadeDuration = _ref_fadeDuration === void 0 ? 250 : _ref_fadeDuration, _ref_easing = _ref.easing, easing = _ref_easing === void 0 ? 'ease-out' : _ref_easing;
70
+ var _useState = _sliced_to_array(useState(false), 2), animComplete = _useState[0], setAnimComplete = _useState[1];
71
+ var _useState1 = _sliced_to_array(useState(0), 2), animSession = _useState1[0], setAnimSession = _useState1[1];
142
72
  var prevTextRef = useRef('');
143
73
  var text = extractText(children);
144
- var hasElementContent = hasElementNode(children);
145
74
  useEffect(function() {
146
- if (hasElementContent) {
75
+ if (text === prevTextRef.current) return;
76
+ var prev = prevTextRef.current;
77
+ if (!prev) {
78
+ if (!text) return;
147
79
  prevTextRef.current = text;
80
+ setAnimComplete(false);
148
81
  return;
149
82
  }
150
- if (text === prevTextRef.current) return;
151
- if (!prevTextRef.current || !text.startsWith(prevTextRef.current)) {
152
- setChunks([
153
- {
154
- key: '0',
155
- text: text,
156
- content: children,
157
- done: false
158
- }
159
- ]);
83
+ if (isStreamingCompatible(prev, text)) {
160
84
  prevTextRef.current = text;
161
85
  return;
162
86
  }
163
- var prevLen = prevTextRef.current.length;
164
- var newText = text.slice(prevLen);
165
- var newKey = "anim-".concat(Date.now(), "-").concat(prevLen);
166
- setChunks(function(prev) {
167
- return _to_consumable_array(prev).concat([
168
- {
169
- key: newKey,
170
- text: newText,
171
- done: false
172
- }
173
- ]);
87
+ setAnimComplete(false);
88
+ setAnimSession(function(s) {
89
+ return s + 1;
174
90
  });
175
91
  prevTextRef.current = text;
176
92
  }, [
177
- text,
178
- children,
179
- hasElementContent
93
+ text
180
94
  ]);
181
- var handleAnimationEnd = function handleAnimationEnd(key) {
182
- setChunks(function(prev) {
183
- return prev.map(function(c) {
184
- return c.key === key ? _object_spread_props(_object_spread({}, c), {
185
- done: true
186
- }) : c;
187
- });
188
- });
95
+ var handleAnimationEnd = function handleAnimationEnd() {
96
+ return setAnimComplete(true);
189
97
  };
190
98
  var animationStyle = useMemo(function() {
191
99
  return {
@@ -198,29 +106,19 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
198
106
  fadeDuration,
199
107
  easing
200
108
  ]);
201
- /** 动画结束后仍用 inline-block 包裹,避免从 span 变为裸内容时的宽度重排 */ var doneChunkStyle = useMemo(function() {
109
+ var doneChunkStyle = useMemo(function() {
202
110
  return {
203
111
  display: 'inline-block',
204
112
  color: 'inherit'
205
113
  };
206
114
  }, []);
207
- if (hasElementContent) {
208
- return /*#__PURE__*/ React.createElement(React.Fragment, null, children);
209
- }
210
- return /*#__PURE__*/ React.createElement(React.Fragment, null, chunks.map(function(chunk) {
211
- var _chunk_content;
212
- var rendered = (_chunk_content = chunk.content) !== null && _chunk_content !== void 0 ? _chunk_content : chunk.text;
213
- return chunk.done ? /*#__PURE__*/ React.createElement("span", {
214
- key: chunk.key,
215
- style: doneChunkStyle
216
- }, rendered) : /*#__PURE__*/ React.createElement("span", {
217
- key: chunk.key,
218
- style: animationStyle,
219
- onAnimationEnd: function onAnimationEnd() {
220
- return handleAnimationEnd(chunk.key);
221
- }
222
- }, rendered);
223
- }));
115
+ return animComplete ? /*#__PURE__*/ React.createElement("span", {
116
+ style: doneChunkStyle
117
+ }, children) : /*#__PURE__*/ React.createElement("span", {
118
+ key: animSession,
119
+ style: animationStyle,
120
+ onAnimationEnd: handleAnimationEnd
121
+ }, children);
224
122
  });
225
123
  AnimationText.displayName = 'AnimationText';
226
124
  export default AnimationText;
@@ -236,7 +236,7 @@ var SCHEMA_LANGUAGES = new Set([
236
236
  * - Markdown → hast → React 元素树(hast-util-to-jsx-runtime)
237
237
  * - 特殊块(code / mermaid / chart / katex)通过组件映射拦截渲染
238
238
  */ var InternalMarkdownRenderer = /*#__PURE__*/ forwardRef(function(props, ref) {
239
- var content = props.content, _props_streaming = props.streaming, streaming = _props_streaming === void 0 ? false : _props_streaming, isFinished = props.isFinished, queueOptions = props.queueOptions, plugins = props.plugins, remarkPlugins = props.remarkPlugins, htmlConfig = props.htmlConfig, className = props.className, style = props.style, customPrefixCls = props.prefixCls, linkConfig = props.linkConfig, apaasify = props.apaasify;
239
+ var content = props.content, _props_streaming = props.streaming, streaming = _props_streaming === void 0 ? false : _props_streaming, isFinished = props.isFinished, queueOptions = props.queueOptions, plugins = props.plugins, remarkPlugins = props.remarkPlugins, htmlConfig = props.htmlConfig, className = props.className, style = props.style, customPrefixCls = props.prefixCls, linkConfig = props.linkConfig, streamingParagraphAnimation = props.streamingParagraphAnimation, apaasify = props.apaasify;
240
240
  var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
241
241
  // 复用 MarkdownEditor 的 CSS 前缀和样式,保持渲染一致性
242
242
  var prefixCls = getPrefixCls('agentic-md-editor', customPrefixCls);
@@ -249,6 +249,7 @@ var SCHEMA_LANGUAGES = new Set([
249
249
  var containerRef = useRef(null);
250
250
  var _useState = _sliced_to_array(useState(content || ''), 2), displayedContent = _useState[0], setDisplayedContent = _useState[1];
251
251
  var queueRef = useRef(null);
252
+ /** 与 CharacterQueue 构造参数同步,避免 queueOptions 变更后仍用旧队列行为 */ var queueOptsSigRef = useRef('');
252
253
  useImperativeHandle(ref, function() {
253
254
  return {
254
255
  nativeElement: containerRef.current,
@@ -263,10 +264,12 @@ var SCHEMA_LANGUAGES = new Set([
263
264
  }, [
264
265
  plugins
265
266
  ]);
266
- // 字符队列管理:流式时仅对最后 50 字做动画,避免每段逐字输出
267
+ // 字符队列:默认关闭逐字动画,避免 RAF 每帧全量重解析 Markdown 导致整页闪动。
268
+ // 需要打字机效果时显式传入 queueOptions={{ animate: true, animateTailChars?: number }}。
267
269
  var resolvedQueueOptions = useMemo(function() {
268
270
  return streaming ? _object_spread({
269
- animateTailChars: 50
271
+ animate: false,
272
+ animateTailChars: undefined
270
273
  }, queueOptions) : queueOptions;
271
274
  }, [
272
275
  streaming,
@@ -274,17 +277,23 @@ var SCHEMA_LANGUAGES = new Set([
274
277
  ]);
275
278
  useEffect(function() {
276
279
  if (!streaming) {
277
- // 非流式:直接展示全部内容
280
+ var _queueRef_current;
278
281
  setDisplayedContent(content || '');
282
+ (_queueRef_current = queueRef.current) === null || _queueRef_current === void 0 ? void 0 : _queueRef_current.dispose();
283
+ queueRef.current = null;
284
+ queueOptsSigRef.current = '';
279
285
  return;
280
286
  }
281
- if (!queueRef.current) {
287
+ var sig = JSON.stringify(resolvedQueueOptions !== null && resolvedQueueOptions !== void 0 ? resolvedQueueOptions : {});
288
+ if (!queueRef.current || sig !== queueOptsSigRef.current) {
289
+ var _queueRef_current1;
290
+ (_queueRef_current1 = queueRef.current) === null || _queueRef_current1 === void 0 ? void 0 : _queueRef_current1.dispose();
282
291
  queueRef.current = new CharacterQueue(function(displayed) {
283
292
  return setDisplayedContent(displayed);
284
293
  }, resolvedQueueOptions);
294
+ queueOptsSigRef.current = sig;
285
295
  }
286
296
  queueRef.current.push(content || '');
287
- return undefined;
288
297
  }, [
289
298
  content,
290
299
  streaming,
@@ -347,7 +356,8 @@ var SCHEMA_LANGUAGES = new Set([
347
356
  components: components,
348
357
  prefixCls: prefixCls,
349
358
  linkConfig: linkConfig,
350
- streaming: streaming
359
+ streaming: streaming,
360
+ streamingParagraphAnimation: streamingParagraphAnimation
351
361
  });
352
362
  return wrapVarSSR(wrapSSR(wrapContentSSR(/*#__PURE__*/ React.createElement("div", {
353
363
  ref: containerRef,
@@ -359,7 +369,7 @@ var SCHEMA_LANGUAGES = new Set([
359
369
  display: 'block'
360
370
  }
361
371
  }, /*#__PURE__*/ React.createElement("div", {
362
- className: clsx(contentCls, hashId),
372
+ className: clsx(contentCls, "".concat(contentCls, "-markdown-readonly"), hashId),
363
373
  style: {
364
374
  whiteSpace: 'normal',
365
375
  wordWrap: 'normal'
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ /** 仅末块为 true:流式 Markdown 只对「当前生长块」播放入场,避免全页段落/表格单元格一起闪动 */
3
+ export interface StreamingAnimationContextValue {
4
+ animateBlock: boolean;
5
+ }
6
+ export declare const StreamingAnimationContext: React.Context<StreamingAnimationContextValue | null>;
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export var StreamingAnimationContext = /*#__PURE__*/ React.createContext(null);
@@ -4,7 +4,10 @@ import type { MarkdownEditorPlugin } from '../MarkdownEditor/plugin';
4
4
  export interface CharacterQueueOptions {
5
5
  /** 每帧输出的最大字符数,默认 3 */
6
6
  charsPerFrame?: number;
7
- /** 是否启用打字动画,默认 true(流式时) */
7
+ /**
8
+ * 是否启用 CharacterQueue 逐字输出(RAF 驱动)。
9
+ * MarkdownRenderer 流式默认合并为 `false`,避免每帧全量重解析导致整页闪动;需打字机时再设为 `true`。
10
+ */
8
11
  animate?: boolean;
9
12
  /**
10
13
  * 仅对末尾 N 个字符做动画,前面内容立即展示。
@@ -65,6 +68,11 @@ export interface MarkdownRendererProps {
65
68
  /** 自定义链接点击处理,返回 false 可阻止默认跳转 */
66
69
  onClick?: (url?: string) => boolean | void;
67
70
  };
71
+ /**
72
+ * 流式时是否为生长中的末段启用淡入(AnimationText)。
73
+ * 默认 false,避免重解析时整页闪动;需要段落入场效果时再设为 true。
74
+ */
75
+ streamingParagraphAnimation?: boolean;
68
76
  /** Apaasify / Schema 自定义渲染 */
69
77
  apaasify?: {
70
78
  enable?: boolean;
@@ -14,6 +14,11 @@ interface UseMarkdownToReactOptions {
14
14
  };
15
15
  /** 是否处于流式状态,用于最后一个块的打字动画 */
16
16
  streaming?: boolean;
17
+ /**
18
+ * 流式时是否对「生长中的末段」启用段落淡入(AnimationText)。
19
+ * 默认 false:重解析时频繁触发动画易导致整页闪动;需要时再显式传入 true。
20
+ */
21
+ streamingParagraphAnimation?: boolean;
17
22
  }
18
23
  export declare const useMarkdownToReact: (content: string, options?: UseMarkdownToReactOptions) => React.ReactNode;
19
24
  /**
@@ -122,7 +122,7 @@ function _unsupported_iterable_to_array(o, minLen) {
122
122
  }
123
123
  import { Checkbox, Image } from "antd";
124
124
  import { toJsxRuntime } from "hast-util-to-jsx-runtime";
125
- import React, { useMemo, useRef } from "react";
125
+ import React, { useContext, useMemo, useRef } from "react";
126
126
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
127
127
  import rehypeKatex from "rehype-katex";
128
128
  import rehypeRaw from "rehype-raw";
@@ -141,6 +141,7 @@ import { REMARK_REHYPE_DIRECTIVE_HANDLERS } from "../MarkdownEditor/editor/utils
141
141
  import { parseChineseCurrencyToNumber } from "../Plugins/chart/utils";
142
142
  import { ToolUseBarThink } from "../ToolUseBarThink";
143
143
  import AnimationText from "./AnimationText";
144
+ import { StreamingAnimationContext } from "./StreamingAnimationContext";
144
145
  var INLINE_MATH_WITH_SINGLE_DOLLAR = {
145
146
  singleDollarTextMath: true
146
147
  };
@@ -432,14 +433,26 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
432
433
  *
433
434
  * MarkdownEditor 的 Slate 元素使用 data-be 属性和 prefixCls 类名,
434
435
  * 这里为原生 HTML 标签添加相同的属性,使共用的 CSS 能正确命中。
435
- */ var buildEditorAlignedComponents = function buildEditorAlignedComponents(prefixCls, userComponents, streaming, linkConfig) {
436
+ */ var buildEditorAlignedComponents = function buildEditorAlignedComponents(prefixCls, userComponents, streaming, linkConfig, streamingParagraphAnimation) {
436
437
  var listCls = "".concat(prefixCls, "-list");
437
438
  var tableCls = "".concat(prefixCls, "-content-table");
438
439
  var contentCls = prefixCls; // e.g. ant-agentic-md-editor-content
440
+ /** 仅当 streaming、末块动画上下文允许且显式开启段落动画时包 AnimationText */ var StreamAnimWrap = function StreamAnimWrap(param) {
441
+ var children = param.children;
442
+ var _ref;
443
+ var ctx = useContext(StreamingAnimationContext);
444
+ var animateBlock = (_ref = ctx === null || ctx === void 0 ? void 0 : ctx.animateBlock) !== null && _ref !== void 0 ? _ref : true;
445
+ var allow = !!streaming && animateBlock && !!streamingParagraphAnimation;
446
+ if (!allow) return children;
447
+ return jsx(AnimationText, {
448
+ children: children
449
+ });
450
+ };
451
+ StreamAnimWrap.displayName = 'StreamAnimWrap';
439
452
  var wrapAnimation = function wrapAnimation(children) {
440
- return streaming ? jsx(AnimationText, {
453
+ return jsx(StreamAnimWrap, {
441
454
  children: children
442
- }) : children;
455
+ });
443
456
  };
444
457
  return _object_spread({
445
458
  // ================================================================
@@ -464,7 +477,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
464
477
  return jsx('h1', _object_spread_props(_object_spread({}, rest), {
465
478
  'data-be': 'head',
466
479
  'data-testid': 'markdown-heading-1',
467
- children: wrapAnimation(children)
480
+ children: children
468
481
  }));
469
482
  },
470
483
  h2: function h2(props) {
@@ -475,7 +488,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
475
488
  return jsx('h2', _object_spread_props(_object_spread({}, rest), {
476
489
  'data-be': 'head',
477
490
  'data-testid': 'markdown-heading-2',
478
- children: wrapAnimation(children)
491
+ children: children
479
492
  }));
480
493
  },
481
494
  h3: function h3(props) {
@@ -486,7 +499,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
486
499
  return jsx('h3', _object_spread_props(_object_spread({}, rest), {
487
500
  'data-be': 'head',
488
501
  'data-testid': 'markdown-heading-3',
489
- children: wrapAnimation(children)
502
+ children: children
490
503
  }));
491
504
  },
492
505
  h4: function h4(props) {
@@ -497,7 +510,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
497
510
  return jsx('h4', _object_spread_props(_object_spread({}, rest), {
498
511
  'data-be': 'head',
499
512
  'data-testid': 'markdown-heading-4',
500
- children: wrapAnimation(children)
513
+ children: children
501
514
  }));
502
515
  },
503
516
  h5: function h5(props) {
@@ -508,7 +521,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
508
521
  return jsx('h5', _object_spread_props(_object_spread({}, rest), {
509
522
  'data-be': 'head',
510
523
  'data-testid': 'markdown-heading-5',
511
- children: wrapAnimation(children)
524
+ children: children
512
525
  }));
513
526
  },
514
527
  h6: function h6(props) {
@@ -519,7 +532,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
519
532
  return jsx('h6', _object_spread_props(_object_spread({}, rest), {
520
533
  'data-be': 'head',
521
534
  'data-testid': 'markdown-heading-6',
522
- children: wrapAnimation(children)
535
+ children: children
523
536
  }));
524
537
  },
525
538
  blockquote: function blockquote(props) {
@@ -607,7 +620,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
607
620
  className: "".concat(listCls, "-item"),
608
621
  'data-be': 'list-item',
609
622
  'data-testid': 'markdown-list-item',
610
- children: wrapAnimation(children)
623
+ children: children
611
624
  }));
612
625
  },
613
626
  table: function table(props) {
@@ -686,7 +699,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
686
699
  whiteSpace: 'normal',
687
700
  maxWidth: '20%'
688
701
  },
689
- children: wrapAnimation(children)
702
+ children: children
690
703
  }));
691
704
  },
692
705
  // input[type=checkbox]:task list 的 checkbox(兜底,主逻辑在 li 中)
@@ -1061,13 +1074,31 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
1061
1074
  }
1062
1075
  }, userComponents);
1063
1076
  };
1077
+ /**
1078
+ * 在 hast 上标记「最后一个 p」,用于流式时仅该段落播放入场(单块长文时避免全页 p 一起闪)
1079
+ */ var markLastParagraphStreamingTail = function markLastParagraphStreamingTail(hast) {
1080
+ var paragraphs = [];
1081
+ visit(hast, 'element', function(node) {
1082
+ if (node.tagName === 'p') {
1083
+ paragraphs.push(node);
1084
+ }
1085
+ });
1086
+ var last = paragraphs[paragraphs.length - 1];
1087
+ if (last) {
1088
+ last.properties = last.properties || {};
1089
+ last.properties.dataStreamingTail = true;
1090
+ }
1091
+ };
1064
1092
  /**
1065
1093
  * 将单个 markdown 片段转为 React 元素(内部函数)
1066
- */ var renderMarkdownBlock = function renderMarkdownBlock(blockContent, processor, components) {
1094
+ */ var renderMarkdownBlock = function renderMarkdownBlock(blockContent, processor, components, blockOpts) {
1067
1095
  if (!blockContent.trim()) return null;
1068
1096
  try {
1069
1097
  var mdast = processor.parse(blockContent);
1070
1098
  var hast = processor.runSync(mdast);
1099
+ if (blockOpts === null || blockOpts === void 0 ? void 0 : blockOpts.markStreamingTailParagraph) {
1100
+ markLastParagraphStreamingTail(hast);
1101
+ }
1071
1102
  return toJsxRuntime(hast, {
1072
1103
  Fragment: Fragment,
1073
1104
  jsx: jsx,
@@ -1098,7 +1129,9 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
1098
1129
  if (!inFence && line === '' && current.length > 0) {
1099
1130
  var prev = current[current.length - 1];
1100
1131
  if (prev === '') {
1101
- blocks.push(current.join('\n'));
1132
+ // 触发分割的是「第二个连续空行」,不应并入上一块末尾,否则与单块解析结果字符串不一致、缓存失效
1133
+ var withoutTrailingBlank = current.slice(0, -1);
1134
+ blocks.push(withoutTrailingBlank.join('\n'));
1102
1135
  current = [];
1103
1136
  continue;
1104
1137
  }
@@ -1152,6 +1185,7 @@ export var useMarkdownToReact = function useMarkdownToReact(content, options) {
1152
1185
  var processorRef = useRef(null);
1153
1186
  var blockCacheRef = useRef(new Map());
1154
1187
  var lastBlockRef = useRef(null);
1188
+ var prevContentRef = useRef('');
1155
1189
  var processor = useMemo(function() {
1156
1190
  var p = createHastProcessor(options === null || options === void 0 ? void 0 : options.remarkPlugins, options === null || options === void 0 ? void 0 : options.htmlConfig);
1157
1191
  processorRef.current = p;
@@ -1163,15 +1197,25 @@ export var useMarkdownToReact = function useMarkdownToReact(content, options) {
1163
1197
  var prefixCls = (options === null || options === void 0 ? void 0 : options.prefixCls) || 'ant-agentic-md-editor';
1164
1198
  var components = useMemo(function() {
1165
1199
  var userComponents = (options === null || options === void 0 ? void 0 : options.components) || {};
1166
- return buildEditorAlignedComponents(prefixCls, userComponents, options === null || options === void 0 ? void 0 : options.streaming, options === null || options === void 0 ? void 0 : options.linkConfig);
1200
+ return buildEditorAlignedComponents(prefixCls, userComponents, options === null || options === void 0 ? void 0 : options.streaming, options === null || options === void 0 ? void 0 : options.linkConfig, options === null || options === void 0 ? void 0 : options.streamingParagraphAnimation);
1167
1201
  }, [
1168
1202
  prefixCls,
1169
1203
  options === null || options === void 0 ? void 0 : options.components,
1170
1204
  options === null || options === void 0 ? void 0 : options.streaming,
1171
- options === null || options === void 0 ? void 0 : options.linkConfig
1205
+ options === null || options === void 0 ? void 0 : options.linkConfig,
1206
+ options === null || options === void 0 ? void 0 : options.streamingParagraphAnimation
1172
1207
  ]);
1173
1208
  return useMemo(function() {
1174
- if (!content) return null;
1209
+ if (!content) {
1210
+ prevContentRef.current = '';
1211
+ return null;
1212
+ }
1213
+ var prevContent = prevContentRef.current;
1214
+ if (prevContent && content !== prevContent && !content.startsWith(prevContent)) {
1215
+ blockCacheRef.current = new Map();
1216
+ lastBlockRef.current = null;
1217
+ }
1218
+ prevContentRef.current = content;
1175
1219
  try {
1176
1220
  var preprocessed = content.replace(new RegExp(JINJA_DOLLAR_PLACEHOLDER, 'g'), '$');
1177
1221
  var blocks = splitMarkdownBlocks(preprocessed);
@@ -1179,21 +1223,30 @@ export var useMarkdownToReact = function useMarkdownToReact(content, options) {
1179
1223
  var cache = blockCacheRef.current;
1180
1224
  var newCache = new Map();
1181
1225
  var elements = [];
1226
+ var wrapBlockScope = function wrapBlockScope(node, key, animateBlock) {
1227
+ return jsx(StreamingAnimationContext.Provider, {
1228
+ key: key,
1229
+ value: {
1230
+ animateBlock: animateBlock
1231
+ },
1232
+ children: node
1233
+ });
1234
+ };
1235
+ var KEY_PREFIX_LEN = 64;
1182
1236
  for(var i = 0; i < blocks.length; i++){
1183
1237
  var block = blocks[i];
1184
1238
  var isLast = i === blocks.length - 1;
1185
1239
  // 用 index + 内容前 64 字符作 key,保持稳定性:
1186
- // 相同位置 + 相同内容开头 相同 key → React 不 unmount
1187
- // 流式场景下,最后一个块内容频繁变化,若 key 随内容变会导致反复 unmount/remount
1188
- // ChartBlockRenderer 等会重复展示 Loading,故对末块使用稳定 key
1189
- var stableKey = isLast && (options === null || options === void 0 ? void 0 : options.streaming) ? "b".concat(i, "-last") : "b".concat(i, "-").concat(block.slice(0, 64));
1240
+ // - 末块在流式中节流时,用 lastBlockRef.source 的切片作 key,避免每次追加字符导致 key 变化
1241
+ // - 末块变为非末块时,必须与先前 key 一致,否则 ChartBlockRenderer 等会 unmount/remount 闪烁
1242
+ // - 因此统一用「实际展示内容」的 slice key,节流时用 lastBlockRef.source
1243
+ var contentForKey = isLast && (options === null || options === void 0 ? void 0 : options.streaming) && lastBlockRef.current && !shouldReparseLastBlock(lastBlockRef.current.source, block, options === null || options === void 0 ? void 0 : options.streaming) ? lastBlockRef.current.source.slice(0, KEY_PREFIX_LEN) : block.slice(0, KEY_PREFIX_LEN);
1244
+ var stableKey = "b".concat(i, "-").concat(contentForKey);
1190
1245
  if (!isLast) {
1191
1246
  var cached = cache.get(block);
1192
1247
  if (cached && cached.source === block) {
1193
1248
  newCache.set(block, cached);
1194
- elements.push(jsx(Fragment, {
1195
- children: cached.element
1196
- }, stableKey));
1249
+ elements.push(wrapBlockScope(cached.element, stableKey, false));
1197
1250
  continue;
1198
1251
  }
1199
1252
  }
@@ -1204,22 +1257,20 @@ export var useMarkdownToReact = function useMarkdownToReact(content, options) {
1204
1257
  source: lastBlockRef.current.source,
1205
1258
  element: lastBlockRef.current.element
1206
1259
  });
1207
- elements.push(jsx(Fragment, {
1208
- children: lastBlockRef.current.element
1209
- }, stableKey));
1260
+ elements.push(wrapBlockScope(lastBlockRef.current.element, stableKey, !!(options === null || options === void 0 ? void 0 : options.streaming)));
1210
1261
  continue;
1211
1262
  }
1212
1263
  }
1213
- var element = renderMarkdownBlock(block, processor, components);
1264
+ var element = renderMarkdownBlock(block, processor, components, {
1265
+ markStreamingTailParagraph: isLast && !!(options === null || options === void 0 ? void 0 : options.streaming)
1266
+ });
1214
1267
  var entry = {
1215
1268
  source: block,
1216
1269
  element: element
1217
1270
  };
1218
1271
  newCache.set(block, entry);
1219
1272
  if (isLast) lastBlockRef.current = entry;
1220
- elements.push(jsx(Fragment, {
1221
- children: element
1222
- }, stableKey));
1273
+ elements.push(wrapBlockScope(element, stableKey, isLast && !!(options === null || options === void 0 ? void 0 : options.streaming)));
1223
1274
  }
1224
1275
  blockCacheRef.current = newCache;
1225
1276
  return jsxs(Fragment, {
@@ -1246,7 +1297,7 @@ export var useMarkdownToReact = function useMarkdownToReact(content, options) {
1246
1297
  var mdast = processor.parse(preprocessed);
1247
1298
  var hast = processor.runSync(mdast);
1248
1299
  var userComps = components || {};
1249
- var allComponents = buildEditorAlignedComponents('ant-agentic-md-editor', userComps, false);
1300
+ var allComponents = buildEditorAlignedComponents('ant-agentic-md-editor', userComps, false, undefined, false);
1250
1301
  return toJsxRuntime(hast, {
1251
1302
  Fragment: Fragment,
1252
1303
  jsx: jsx,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ant-design/agentic-ui",
3
- "version": "2.30.4",
3
+ "version": "2.30.6",
4
4
  "description": "面向智能体的 UI 组件库,提供多步推理可视化、工具调用展示、任务执行协同等 Agentic UI 能力",
5
5
  "repository": "git@github.com:ant-design/agentic-ui.git",
6
6
  "license": "MIT",