@ant-design/agentic-ui 2.30.5 → 2.30.7

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.
@@ -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,9 +17,7 @@ export interface AnimationTextProps {
12
17
  /**
13
18
  * 流式文字淡入动画组件。
14
19
  *
15
- * 采用 opacity + translateY(GPU 硬件加速),清爽流派。
16
- * 同一段流式前缀追加只触发**一次**入场动画;后续增量仅更新文案。内容被替换
17
- * (非前缀增长)时重新播放入场。动画结束后仍用 span 包裹以保持布局稳定。
20
+ * 同一段流式前缀追加(或尾部截断修正)只触发一次入场动画;非前缀替换时重播。
18
21
  */
19
22
  declare const AnimationText: React.NamedExoticComponent<AnimationTextProps>;
20
23
  export default AnimationText;
@@ -57,34 +57,21 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
57
57
  }
58
58
  return '';
59
59
  };
60
- /**
61
- * 识别 children 中是否包含 React 元素节点。
62
- * 富文本结构(链接、脚注、图片等)在纯文本差分下会丢失结构信息,直接透传更安全。
63
- */ var hasElementNode = function hasElementNode1(children) {
64
- if (children === null || children === undefined || typeof children === 'boolean') return false;
65
- if (typeof children === 'string' || typeof children === 'number') return false;
66
- if (Array.isArray(children)) return children.some(hasElementNode);
67
- return /*#__PURE__*/ React.isValidElement(children);
60
+ /** 流式同一段内:前后文案仅「前缀关系」变化(增长或尾部截断修正) */ var isStreamingCompatible = function isStreamingCompatible(prev, next) {
61
+ return prev.startsWith(next) || next.startsWith(prev);
68
62
  };
69
63
  /**
70
64
  * 流式文字淡入动画组件。
71
65
  *
72
- * 采用 opacity + translateY(GPU 硬件加速),清爽流派。
73
- * 同一段流式前缀追加只触发**一次**入场动画;后续增量仅更新文案。内容被替换
74
- * (非前缀增长)时重新播放入场。动画结束后仍用 span 包裹以保持布局稳定。
66
+ * 同一段流式前缀追加(或尾部截断修正)只触发一次入场动画;非前缀替换时重播。
75
67
  */ var AnimationText = /*#__PURE__*/ React.memo(function(param) {
76
68
  var children = param.children, animationConfig = param.animationConfig;
77
- 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;
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;
78
70
  var _useState = _sliced_to_array(useState(false), 2), animComplete = _useState[0], setAnimComplete = _useState[1];
79
71
  var _useState1 = _sliced_to_array(useState(0), 2), animSession = _useState1[0], setAnimSession = _useState1[1];
80
72
  var prevTextRef = useRef('');
81
73
  var text = extractText(children);
82
- var hasElementContent = hasElementNode(children);
83
74
  useEffect(function() {
84
- if (hasElementContent) {
85
- prevTextRef.current = text;
86
- return;
87
- }
88
75
  if (text === prevTextRef.current) return;
89
76
  var prev = prevTextRef.current;
90
77
  if (!prev) {
@@ -93,7 +80,7 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
93
80
  setAnimComplete(false);
94
81
  return;
95
82
  }
96
- if (text.length > prev.length && text.startsWith(prev)) {
83
+ if (isStreamingCompatible(prev, text)) {
97
84
  prevTextRef.current = text;
98
85
  return;
99
86
  }
@@ -103,8 +90,7 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
103
90
  });
104
91
  prevTextRef.current = text;
105
92
  }, [
106
- text,
107
- hasElementContent
93
+ text
108
94
  ]);
109
95
  var handleAnimationEnd = function handleAnimationEnd() {
110
96
  return setAnimComplete(true);
@@ -120,15 +106,12 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
120
106
  fadeDuration,
121
107
  easing
122
108
  ]);
123
- /** 动画结束后仍用 inline-block 包裹,避免从 span 变为裸内容时的宽度重排 */ var doneChunkStyle = useMemo(function() {
109
+ var doneChunkStyle = useMemo(function() {
124
110
  return {
125
111
  display: 'inline-block',
126
112
  color: 'inherit'
127
113
  };
128
114
  }, []);
129
- if (hasElementContent) {
130
- return /*#__PURE__*/ React.createElement(React.Fragment, null, children);
131
- }
132
115
  return animComplete ? /*#__PURE__*/ React.createElement("span", {
133
116
  style: doneChunkStyle
134
117
  }, children) : /*#__PURE__*/ React.createElement("span", {
@@ -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,9 @@ 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,
361
+ contentRevisionSource: streaming ? displayedContent : undefined
351
362
  });
352
363
  return wrapVarSSR(wrapSSR(wrapContentSSR(/*#__PURE__*/ React.createElement("div", {
353
364
  ref: containerRef,
@@ -359,7 +370,7 @@ var SCHEMA_LANGUAGES = new Set([
359
370
  display: 'block'
360
371
  }
361
372
  }, /*#__PURE__*/ React.createElement("div", {
362
- className: clsx(contentCls, hashId),
373
+ className: clsx(contentCls, "".concat(contentCls, "-markdown-readonly"), hashId),
363
374
  style: {
364
375
  whiteSpace: 'normal',
365
376
  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);
@@ -7,5 +7,7 @@ export { CodeBlockRenderer } from './renderers/CodeRenderer';
7
7
  export { MermaidBlockRenderer } from './renderers/MermaidRenderer';
8
8
  export { SchemaBlockRenderer } from './renderers/SchemaRenderer';
9
9
  export type { CharacterQueueOptions, MarkdownRendererProps, MarkdownRendererRef, RenderMode, RendererBlockProps, } from './types';
10
+ export type { UseMarkdownToReactOptions } from './markdownReactShared';
10
11
  export { markdownToReactSync, useMarkdownToReact } from './useMarkdownToReact';
12
+ export { useStreamingMarkdownReact } from './streaming/useStreamingMarkdownReact';
11
13
  export { useStreaming } from './useStreaming';
@@ -6,4 +6,5 @@ export { CodeBlockRenderer } from "./renderers/CodeRenderer";
6
6
  export { MermaidBlockRenderer } from "./renderers/MermaidRenderer";
7
7
  export { SchemaBlockRenderer } from "./renderers/SchemaRenderer";
8
8
  export { markdownToReactSync, useMarkdownToReact } from "./useMarkdownToReact";
9
+ export { useStreamingMarkdownReact } from "./streaming/useStreamingMarkdownReact";
9
10
  export { useStreaming } from "./useStreaming";
@@ -0,0 +1,93 @@
1
+ import React from 'react';
2
+ import type { Processor } from 'unified';
3
+ import { type MarkdownRemarkPlugin, type MarkdownToHtmlConfig } from '../MarkdownEditor/editor/utils/markdownToHtml';
4
+ import type { RendererBlockProps } from './types';
5
+ declare const createHastProcessor: (extraRemarkPlugins?: MarkdownRemarkPlugin[], config?: MarkdownToHtmlConfig) => Processor;
6
+ /**
7
+ * 构建与 MarkdownEditor Readonly 组件对齐的 hast→React 组件映射。
8
+ *
9
+ * MarkdownEditor 的 Slate 元素使用 data-be 属性和 prefixCls 类名,
10
+ * 这里为原生 HTML 标签添加相同的属性,使共用的 CSS 能正确命中。
11
+ */
12
+ declare const buildEditorAlignedComponents: (prefixCls: string, userComponents: Record<string, React.ComponentType<RendererBlockProps>>, streaming?: boolean, linkConfig?: {
13
+ openInNewTab?: boolean | undefined;
14
+ onClick?: ((url?: string) => boolean | void) | undefined;
15
+ } | undefined, streamingParagraphAnimation?: boolean) => {
16
+ p: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
17
+ h1: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
18
+ h2: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
19
+ h3: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
20
+ h4: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
21
+ h5: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
22
+ h6: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
23
+ blockquote: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
24
+ ul: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
25
+ ol: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
26
+ li: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
27
+ table: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
28
+ thead: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
29
+ tbody: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
30
+ tr: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
31
+ th: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
32
+ td: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
33
+ input: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
34
+ a: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
35
+ strong: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
36
+ em: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
37
+ del: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
38
+ code: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
39
+ mark: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
40
+ kbd: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
41
+ sub: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
42
+ pre: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
43
+ img: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
44
+ video: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
45
+ audio: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
46
+ iframe: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
47
+ hr: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
48
+ sup: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
49
+ span: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
50
+ section: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
51
+ think: (props: any) => React.FunctionComponentElement<import("../ToolUseBarThink").ToolUseBarThinkProps>;
52
+ answer: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
53
+ };
54
+ /**
55
+ * 在 hast 上标记「最后一个 p」,用于流式时仅该段落播放入场(单块长文时避免全页 p 一起闪)
56
+ */
57
+ declare const markLastParagraphStreamingTail: (hast: any) => void;
58
+ /**
59
+ * 将单个 markdown 片段转为 React 元素(内部函数)
60
+ */
61
+ declare const renderMarkdownBlock: (blockContent: string, processor: Processor, components: Record<string, any>, blockOpts?: {
62
+ markStreamingTailParagraph?: boolean;
63
+ }) => React.ReactNode;
64
+ /**
65
+ * 将 markdown 按块(双换行)拆分,尊重代码围栏边界。
66
+ * 返回的每个块是一个独立的 markdown 片段,可单独解析。
67
+ */
68
+ declare const splitMarkdownBlocks: (content: string) => string[];
69
+ export interface UseMarkdownToReactOptions {
70
+ remarkPlugins?: MarkdownRemarkPlugin[];
71
+ htmlConfig?: MarkdownToHtmlConfig;
72
+ components?: Record<string, React.ComponentType<RendererBlockProps>>;
73
+ /** MarkdownEditor 的 CSS 前缀,用于生成对齐的 className */
74
+ prefixCls?: string;
75
+ /** 链接配置:onClick 拦截、openInNewTab 控制 */
76
+ linkConfig?: {
77
+ openInNewTab?: boolean;
78
+ onClick?: (url?: string) => boolean | void;
79
+ };
80
+ /** 是否处于流式状态,用于最后一个块的打字动画 */
81
+ streaming?: boolean;
82
+ /**
83
+ * 流式时是否对「生长中的末段」启用段落淡入(AnimationText)。
84
+ * 默认 false:重解析时频繁触发动画易导致整页闪动;需要时再显式传入 true。
85
+ */
86
+ streamingParagraphAnimation?: boolean;
87
+ /**
88
+ * 单调增长的原始流字符串,仅用于判断是否应保留分块缓存。
89
+ * 与 `content`(常为 useStreaming 输出的可解析串)分离,避免占位符与正文切换时误判为非前缀修订。
90
+ */
91
+ contentRevisionSource?: string;
92
+ }
93
+ export { createHastProcessor, buildEditorAlignedComponents, markLastParagraphStreamingTail, renderMarkdownBlock, splitMarkdownBlocks, };