@ant-design/agentic-ui 2.30.21 → 2.30.23

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 (107) hide show
  1. package/dist/Bubble/MessagesContent/MarkdownPreview.d.ts +0 -58
  2. package/dist/Bubble/MessagesContent/MarkdownPreview.js +79 -155
  3. package/dist/Bubble/OpenAIMessageBubble/index.d.ts +11 -0
  4. package/dist/Bubble/OpenAIMessageBubble/index.js +8 -0
  5. package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.d.ts +7 -0
  6. package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.js +136 -0
  7. package/dist/Bubble/OpenAIMessageBubble/mapOpenAIMessages.d.ts +8 -0
  8. package/dist/Bubble/OpenAIMessageBubble/mapOpenAIMessages.js +156 -0
  9. package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.d.ts +8 -0
  10. package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.js +127 -0
  11. package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.d.ts +16 -0
  12. package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.js +110 -0
  13. package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.d.ts +10 -0
  14. package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.js +61 -0
  15. package/dist/Bubble/OpenAIMessageBubble/ollamaTypes.d.ts +48 -0
  16. package/dist/Bubble/OpenAIMessageBubble/ollamaTypes.js +1 -0
  17. package/dist/Bubble/OpenAIMessageBubble/openClawTypes.d.ts +27 -0
  18. package/dist/Bubble/OpenAIMessageBubble/openClawTypes.js +1 -0
  19. package/dist/Bubble/OpenAIMessageBubble/types.d.ts +71 -0
  20. package/dist/Bubble/OpenAIMessageBubble/types.js +1 -0
  21. package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.d.ts +7 -0
  22. package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.js +23 -0
  23. package/dist/Bubble/OpenAIMessageBubble/useOpenAIMessageBubbleData.d.ts +6 -0
  24. package/dist/Bubble/OpenAIMessageBubble/useOpenAIMessageBubbleData.js +20 -0
  25. package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.d.ts +7 -0
  26. package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.js +22 -0
  27. package/dist/Bubble/index.d.ts +2 -0
  28. package/dist/Bubble/index.js +1 -0
  29. package/dist/Hooks/useAutoScroll.js +6 -4
  30. package/dist/MarkdownEditor/BaseMarkdownEditor.d.ts +1 -50
  31. package/dist/MarkdownEditor/BaseMarkdownEditor.js +11 -55
  32. package/dist/MarkdownEditor/editor/Editor.js +35 -21
  33. package/dist/MarkdownEditor/editor/elements/Code/index.js +1 -0
  34. package/dist/MarkdownEditor/editor/elements/Table/SimpleTable.js +5 -1
  35. package/dist/MarkdownEditor/editor/elements/Table/commands/tableCommands.js +24 -8
  36. package/dist/MarkdownEditor/editor/elements/index.js +18 -14
  37. package/dist/MarkdownEditor/editor/plugins/elements.d.ts +2 -0
  38. package/dist/MarkdownEditor/editor/plugins/elements.js +4 -2
  39. package/dist/MarkdownEditor/editor/plugins/handlePaste.js +46 -35
  40. package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/backspace.js +133 -133
  41. package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/enter.js +156 -140
  42. package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/match.d.ts +2 -1
  43. package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/match.js +23 -4
  44. package/dist/MarkdownEditor/editor/plugins/hotKeyCommands/tab.js +40 -36
  45. package/dist/MarkdownEditor/editor/plugins/useKeyboard.js +46 -44
  46. package/dist/MarkdownEditor/editor/plugins/withCodeTagPlugin.js +1 -13
  47. package/dist/MarkdownEditor/editor/store.d.ts +15 -1
  48. package/dist/MarkdownEditor/editor/store.js +45 -34
  49. package/dist/MarkdownEditor/editor/tools/InsertAutocomplete.js +15 -11
  50. package/dist/MarkdownEditor/editor/utils/editorCommands.js +98 -17
  51. package/dist/MarkdownEditor/editor/utils/editorUtils.d.ts +11 -0
  52. package/dist/MarkdownEditor/editor/utils/editorUtils.js +43 -6
  53. package/dist/MarkdownEditor/editor/utils/keyboard.js +14 -12
  54. package/dist/MarkdownEditor/types.d.ts +36 -414
  55. package/dist/MarkdownEditor/types.js +1 -4
  56. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.d.ts +1 -1
  57. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +4 -5
  58. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/index.d.ts +1 -1
  59. package/dist/MarkdownInputField/AttachmentButton/index.d.ts +1 -1
  60. package/dist/MarkdownInputField/MarkdownInputField.js +8 -1
  61. package/dist/MarkdownInputField/SendActions/index.js +7 -4
  62. package/dist/MarkdownInputField/SendButton/index.d.ts +6 -0
  63. package/dist/MarkdownInputField/SendButton/index.js +6 -0
  64. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.d.ts +2 -1
  65. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.js +12 -3
  66. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldRefs.d.ts +1 -0
  67. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldRefs.js +36 -5
  68. package/dist/MarkdownInputField/utils/renderHelpers.js +5 -0
  69. package/dist/MarkdownRenderer/AnimationText.d.ts +1 -5
  70. package/dist/MarkdownRenderer/AnimationText.js +2 -8
  71. package/dist/MarkdownRenderer/CharacterQueue.d.ts +0 -2
  72. package/dist/MarkdownRenderer/CharacterQueue.js +2 -2
  73. package/dist/MarkdownRenderer/FncRefForMarkdown.d.ts +24 -0
  74. package/dist/MarkdownRenderer/FncRefForMarkdown.js +65 -0
  75. package/dist/MarkdownRenderer/MarkdownRenderer.d.ts +1 -9
  76. package/dist/MarkdownRenderer/MarkdownRenderer.js +25 -18
  77. package/dist/MarkdownRenderer/StreamingCursor.d.ts +4 -0
  78. package/dist/MarkdownRenderer/StreamingCursor.js +20 -0
  79. package/dist/MarkdownRenderer/extractFootnoteDefinitions.d.ts +13 -0
  80. package/dist/MarkdownRenderer/extractFootnoteDefinitions.js +40 -0
  81. package/dist/MarkdownRenderer/markdownReactShared.d.ts +11 -38
  82. package/dist/MarkdownRenderer/markdownReactShared.js +28 -54
  83. package/dist/MarkdownRenderer/renderers/ChartRenderer.js +9 -1
  84. package/dist/MarkdownRenderer/renderers/CodeRenderer.d.ts +4 -1
  85. package/dist/MarkdownRenderer/renderers/CodeRenderer.js +27 -3
  86. package/dist/MarkdownRenderer/renderers/SchemaRenderer.d.ts +2 -0
  87. package/dist/MarkdownRenderer/renderers/SchemaRenderer.js +33 -5
  88. package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.d.ts +1 -3
  89. package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.js +16 -28
  90. package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +2 -1
  91. package/dist/MarkdownRenderer/style.js +18 -0
  92. package/dist/MarkdownRenderer/types.d.ts +17 -93
  93. package/dist/MarkdownRenderer/useMarkdownToReact.js +1 -1
  94. package/dist/MarkdownRenderer/useStreaming.d.ts +1 -10
  95. package/dist/MarkdownRenderer/useStreaming.js +5 -13
  96. package/dist/Plugins/mermaid/MermaidRendererImpl.js +481 -7
  97. package/dist/Plugins/mermaid/style.js +71 -22
  98. package/dist/Plugins/mermaid/useMermaidRender.d.ts +2 -1
  99. package/dist/Plugins/mermaid/useMermaidRender.js +41 -13
  100. package/dist/Plugins/mermaid/utils.d.ts +16 -0
  101. package/dist/Plugins/mermaid/utils.js +197 -5
  102. package/dist/ThoughtChainList/MarkdownEditor.d.ts +1 -35
  103. package/dist/ThoughtChainList/MarkdownEditor.js +5 -44
  104. package/dist/Workspace/Browser/index.js +19 -1
  105. package/dist/Workspace/RealtimeFollow/index.d.ts +3 -0
  106. package/dist/Workspace/RealtimeFollow/index.js +5 -3
  107. package/package.json +8 -7
@@ -0,0 +1,13 @@
1
+ /** 与 `fncProps.onFootnoteDefinitionChange` 数组元素一致 */
2
+ export interface FootnoteDefinitionRow {
3
+ id: any;
4
+ placeholder: any;
5
+ origin_text: any;
6
+ url: any;
7
+ origin_url: any;
8
+ }
9
+ /**
10
+ * 从 Markdown 源码提取 GFM 脚注定义,结构与 Slate 只读 Editor 中
11
+ * `fncProps.onFootnoteDefinitionChange` 入参对齐。
12
+ */
13
+ export declare const extractFootnoteDefinitionsFromMarkdown: (content: string) => FootnoteDefinitionRow[];
@@ -0,0 +1,40 @@
1
+ import remarkGfm from "remark-gfm";
2
+ import remarkParse from "remark-parse";
3
+ import { unified } from "unified";
4
+ import { visit } from "unist-util-visit";
5
+ var mdastFootnoteProcessor = unified().use(remarkParse).use(remarkGfm, {
6
+ singleTilde: false
7
+ });
8
+ var mdastPlainText = function mdastPlainText1(node) {
9
+ if (!node) return '';
10
+ if (node.type === 'text') return node.value || '';
11
+ if (Array.isArray(node.children)) {
12
+ return node.children.map(mdastPlainText).join('');
13
+ }
14
+ return '';
15
+ };
16
+ /**
17
+ * 从 Markdown 源码提取 GFM 脚注定义,结构与 Slate 只读 Editor 中
18
+ * `fncProps.onFootnoteDefinitionChange` 入参对齐。
19
+ */ export var extractFootnoteDefinitionsFromMarkdown = function extractFootnoteDefinitionsFromMarkdown(content) {
20
+ if (!(content === null || content === void 0 ? void 0 : content.trim())) return [];
21
+ try {
22
+ var tree = mdastFootnoteProcessor.parse(content);
23
+ var list = [];
24
+ visit(tree, 'footnoteDefinition', function(node) {
25
+ var _node_label;
26
+ list.push({
27
+ id: node.identifier,
28
+ placeholder: (_node_label = node.label) !== null && _node_label !== void 0 ? _node_label : node.identifier,
29
+ origin_text: mdastPlainText({
30
+ children: node.children
31
+ }),
32
+ url: undefined,
33
+ origin_url: undefined
34
+ });
35
+ });
36
+ return list;
37
+ } catch (unused) {
38
+ return [];
39
+ }
40
+ };
@@ -1,18 +1,14 @@
1
1
  import React from 'react';
2
2
  import type { Processor } from 'unified';
3
3
  import { type MarkdownRemarkPlugin, type MarkdownToHtmlConfig } from '../MarkdownEditor/editor/utils/markdownToHtml';
4
+ import type { MarkdownEditorProps } from '../MarkdownEditor/types';
4
5
  import type { MarkdownRendererEleProps, RendererBlockProps } from './types';
5
6
  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
- */
7
+ /** hast → React 组件映射,与 MarkdownEditor Readonly 的 data-be / prefixCls 对齐 */
12
8
  declare const buildEditorAlignedComponents: (prefixCls: string, userComponents: Record<string, React.ComponentType<RendererBlockProps>>, streaming?: boolean, linkConfig?: {
13
9
  openInNewTab?: boolean | undefined;
14
10
  onClick?: ((url?: string) => boolean | void) | undefined;
15
- } | undefined, streamingParagraphAnimation?: boolean, eleRender?: ((props: MarkdownRendererEleProps, defaultDom: React.ReactNode) => React.ReactNode) | undefined) => {
11
+ } | undefined, fncProps?: MarkdownEditorProps['fncProps'], streamingParagraphAnimation?: boolean, eleRender?: ((props: MarkdownRendererEleProps, defaultDom: React.ReactNode) => React.ReactNode) | undefined) => {
16
12
  p: (props: any) => React.ReactNode;
17
13
  h1: (props: any) => React.ReactNode;
18
14
  h2: (props: any) => React.ReactNode;
@@ -51,50 +47,27 @@ declare const buildEditorAlignedComponents: (prefixCls: string, userComponents:
51
47
  think: (props: any) => React.FunctionComponentElement<import("../ToolUseBarThink").ToolUseBarThinkProps>;
52
48
  answer: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
53
49
  };
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
- */
50
+ /** markdown 片段 → React 元素 */
51
+ declare const renderMarkdownBlock: (blockContent: string, processor: Processor, components: Record<string, any>) => React.ReactNode;
52
+ /** 按双换行拆块,尊重代码围栏边界 */
68
53
  declare const splitMarkdownBlocks: (content: string) => string[];
69
54
  export interface UseMarkdownToReactOptions {
70
55
  remarkPlugins?: MarkdownRemarkPlugin[];
71
56
  htmlConfig?: MarkdownToHtmlConfig;
72
57
  components?: Record<string, React.ComponentType<RendererBlockProps>>;
73
- /** MarkdownEditor 的 CSS 前缀,用于生成对齐的 className */
74
58
  prefixCls?: string;
75
- /** 链接配置:onClick 拦截、openInNewTab 控制 */
76
59
  linkConfig?: {
77
60
  openInNewTab?: boolean;
78
61
  onClick?: (url?: string) => boolean | void;
79
62
  };
80
- /** 是否处于流式状态,用于最后一个块的打字动画 */
63
+ fncProps?: MarkdownEditorProps['fncProps'];
81
64
  streaming?: boolean;
82
- /**
83
- * 流式时是否对「生长中的末段」启用段落淡入(AnimationText)。
84
- * 默认 false:重解析时频繁触发动画易导致整页闪动;需要时再显式传入 true。
85
- */
65
+ /** 默认开启;传 false 关闭末段段落动画 */
86
66
  streamingParagraphAnimation?: boolean;
87
- /**
88
- * 单调增长的原始流字符串,仅用于判断是否应保留分块缓存。
89
- * 与 `content`(常为 useStreaming 输出的可解析串)分离,避免占位符与正文切换时误判为非前缀修订。
90
- */
67
+ /** 原始流字符串,与 useStreaming 输出分离避免缓存误判 */
91
68
  contentRevisionSource?: string;
92
- /**
93
- * 自定义元素渲染拦截函数(markdown 渲染模式)。
94
- * 允许在默认渲染结果基础上包装、替换任意元素。
95
- * 返回 undefined 时回退到默认渲染。
96
- */
69
+ /** 返回 undefined 回退默认渲染 */
97
70
  eleRender?: (props: MarkdownRendererEleProps, defaultDom: React.ReactNode) => React.ReactNode;
98
71
  }
99
- export { buildEditorAlignedComponents, createHastProcessor, markLastParagraphStreamingTail, renderMarkdownBlock, splitMarkdownBlocks, };
72
+ export { buildEditorAlignedComponents, createHastProcessor, renderMarkdownBlock, splitMarkdownBlocks, };
100
73
  export type { MarkdownRendererEleProps };
@@ -140,6 +140,7 @@ import { REMARK_REHYPE_DIRECTIVE_HANDLERS } from "../MarkdownEditor/editor/utils
140
140
  import { parseChineseCurrencyToNumber } from "../Plugins/chart/utils";
141
141
  import { ToolUseBarThink } from "../ToolUseBarThink";
142
142
  import AnimationText from "./AnimationText";
143
+ import { FncRefForMarkdown, extractFootnoteRefFromSupChildren } from "./FncRefForMarkdown";
143
144
  import { StreamingAnimationContext } from "./StreamingAnimationContext";
144
145
  var INLINE_MATH_WITH_SINGLE_DOLLAR = {
145
146
  singleDollarTextMath: true
@@ -391,9 +392,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
391
392
  }
392
393
  return undefined;
393
394
  };
394
- /**
395
- * 提取 React children 的文本内容
396
- */ var extractChildrenText = function extractChildrenText1(children) {
395
+ var extractChildrenText = function extractChildrenText1(children) {
397
396
  var _children_props;
398
397
  if (typeof children === 'string') return children;
399
398
  if (typeof children === 'number') return String(children);
@@ -403,13 +402,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
403
402
  }
404
403
  return '';
405
404
  };
406
- /**
407
- * <think> 标签渲染组件——使用 ToolUseBarThink 替代原生 DOM。
408
- * 在 MarkdownEditor 中,<think> 被预处理为 ```think 代码块,
409
- * 然后由 ThinkBlock 组件(依赖 Slate 上下文)渲染为 ToolUseBarThink。
410
- * 在 MarkdownRenderer 中,<think> 通过 rehypeRaw 保留为 hast 元素,
411
- * 这里直接渲染为 ToolUseBarThink,无需 Slate 上下文。
412
- */ var ThinkBlockRendererComponent = function ThinkBlockRendererComponent(props) {
405
+ /** <think> 标签 → ToolUseBarThink(MarkdownRenderer 无 Slate 上下文,直接渲染) */ var ThinkBlockRendererComponent = function ThinkBlockRendererComponent(props) {
413
406
  var children = props.children;
414
407
  var content = extractChildrenText(children);
415
408
  var isLoading = content.endsWith('...');
@@ -427,21 +420,16 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
427
420
  status: isLoading ? 'loading' : 'success'
428
421
  });
429
422
  };
430
- /**
431
- * 构建与 MarkdownEditor Readonly 组件对齐的 hast→React 组件映射。
432
- *
433
- * MarkdownEditor 的 Slate 元素使用 data-be 属性和 prefixCls 类名,
434
- * 这里为原生 HTML 标签添加相同的属性,使共用的 CSS 能正确命中。
435
- */ var buildEditorAlignedComponents = function buildEditorAlignedComponents(prefixCls, userComponents, streaming, linkConfig, streamingParagraphAnimation, eleRender) {
423
+ /** hast → React 组件映射,与 MarkdownEditor Readonly 的 data-be / prefixCls 对齐 */ var buildEditorAlignedComponents = function buildEditorAlignedComponents(prefixCls, userComponents, streaming, linkConfig, fncProps, streamingParagraphAnimation, eleRender) {
436
424
  var listCls = "".concat(prefixCls, "-list");
437
425
  var tableCls = "".concat(prefixCls, "-content-table");
438
426
  var contentCls = prefixCls; // e.g. ant-agentic-md-editor-content
439
- /** 仅当 streaming、末块动画上下文允许且显式开启段落动画时包 AnimationText */ var StreamAnimWrap = function StreamAnimWrap(param) {
427
+ /** 仅当 streaming、末块动画上下文允许且未显式关闭段落动画时包 AnimationText */ var StreamAnimWrap = function StreamAnimWrap(param) {
440
428
  var children = param.children;
441
429
  var _ref;
442
430
  var ctx = useContext(StreamingAnimationContext);
443
431
  var animateBlock = (_ref = ctx === null || ctx === void 0 ? void 0 : ctx.animateBlock) !== null && _ref !== void 0 ? _ref : true;
444
- var allow = !!streaming && animateBlock && !!streamingParagraphAnimation;
432
+ var allow = !!streaming && animateBlock && streamingParagraphAnimation !== false;
445
433
  if (!allow) return children;
446
434
  return jsx(AnimationText, {
447
435
  children: children
@@ -887,7 +875,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
887
875
  var defaultDom = jsx('mark', _object_spread_props(_object_spread({}, rest), {
888
876
  'data-testid': 'markdown-mark',
889
877
  style: {
890
- background: '#f59e0b',
878
+ background: 'var(--ant-color-warning-bg, #f59e0b)',
891
879
  padding: '0.1em 0.2em',
892
880
  borderRadius: 2
893
881
  },
@@ -1119,12 +1107,22 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
1119
1107
  node: node
1120
1108
  }, rest), defaultDom);
1121
1109
  },
1122
- // 脚注引用 sup > a(remark-gfm 有定义时生成)
1110
+ // 脚注引用 sup > a(remark-gfm 有定义时生成)— 与 Slate FncLeaf 对齐
1123
1111
  sup: function sup(props) {
1124
1112
  var node = props.node, children = props.children, rest = _object_without_properties(props, [
1125
1113
  "node",
1126
1114
  "children"
1127
1115
  ]);
1116
+ var meta = extractFootnoteRefFromSupChildren(children);
1117
+ if (meta) {
1118
+ return jsx(FncRefForMarkdown, {
1119
+ fncProps: fncProps,
1120
+ linkConfig: linkConfig,
1121
+ identifier: meta.identifier,
1122
+ url: meta.url,
1123
+ children: children
1124
+ });
1125
+ }
1128
1126
  var defaultDom = jsx('span', _object_spread_props(_object_spread({}, rest), {
1129
1127
  'data-fnc': 'fnc',
1130
1128
  'data-testid': 'markdown-footnote-ref',
@@ -1146,15 +1144,14 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
1146
1144
  "children"
1147
1145
  ]);
1148
1146
  if (rest['data-fnc'] === 'fnc') {
1149
- return jsx('span', _object_spread_props(_object_spread({}, rest), {
1150
- 'data-testid': 'markdown-footnote-ref',
1151
- className: "".concat(contentCls, "-fnc"),
1152
- style: {
1153
- fontSize: 12,
1154
- cursor: 'pointer'
1155
- },
1147
+ var raw = rest['data-fnc-name'];
1148
+ var identifier = raw !== undefined && raw !== null && String(raw).length > 0 ? String(raw) : extractChildrenText(children) || '?';
1149
+ return jsx(FncRefForMarkdown, {
1150
+ fncProps: fncProps,
1151
+ linkConfig: linkConfig,
1152
+ identifier: identifier,
1156
1153
  children: children
1157
- }));
1154
+ });
1158
1155
  }
1159
1156
  return jsx('span', _object_spread_props(_object_spread({}, rest), {
1160
1157
  children: children
@@ -1194,31 +1191,11 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
1194
1191
  }
1195
1192
  }, userComponents);
1196
1193
  };
1197
- /**
1198
- * 在 hast 上标记「最后一个 p」,用于流式时仅该段落播放入场(单块长文时避免全页 p 一起闪)
1199
- */ var markLastParagraphStreamingTail = function markLastParagraphStreamingTail(hast) {
1200
- var paragraphs = [];
1201
- visit(hast, 'element', function(node) {
1202
- if (node.tagName === 'p') {
1203
- paragraphs.push(node);
1204
- }
1205
- });
1206
- var last = paragraphs[paragraphs.length - 1];
1207
- if (last) {
1208
- last.properties = last.properties || {};
1209
- last.properties.dataStreamingTail = true;
1210
- }
1211
- };
1212
- /**
1213
- * 将单个 markdown 片段转为 React 元素(内部函数)
1214
- */ var renderMarkdownBlock = function renderMarkdownBlock(blockContent, processor, components, blockOpts) {
1194
+ /** markdown 片段 → React 元素 */ var renderMarkdownBlock = function renderMarkdownBlock(blockContent, processor, components) {
1215
1195
  if (!blockContent.trim()) return null;
1216
1196
  try {
1217
1197
  var mdast = processor.parse(blockContent);
1218
1198
  var hast = processor.runSync(mdast);
1219
- if (blockOpts === null || blockOpts === void 0 ? void 0 : blockOpts.markStreamingTailParagraph) {
1220
- markLastParagraphStreamingTail(hast);
1221
- }
1222
1199
  return toJsxRuntime(hast, {
1223
1200
  Fragment: Fragment,
1224
1201
  jsx: jsx,
@@ -1230,10 +1207,7 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
1230
1207
  return null;
1231
1208
  }
1232
1209
  };
1233
- /**
1234
- * 将 markdown 按块(双换行)拆分,尊重代码围栏边界。
1235
- * 返回的每个块是一个独立的 markdown 片段,可单独解析。
1236
- */ var splitMarkdownBlocks = function splitMarkdownBlocks(content) {
1210
+ /** 按双换行拆块,尊重代码围栏边界 */ var splitMarkdownBlocks = function splitMarkdownBlocks(content) {
1237
1211
  var lines = content.split('\n');
1238
1212
  var blocks = [];
1239
1213
  var current = [];
@@ -1277,4 +1251,4 @@ var extractLanguageFromClassName = function extractLanguageFromClassName(classNa
1277
1251
  }
1278
1252
  return blocks;
1279
1253
  };
1280
- export { buildEditorAlignedComponents, createHastProcessor, markLastParagraphStreamingTail, renderMarkdownBlock, splitMarkdownBlocks };
1254
+ export { buildEditorAlignedComponents, createHastProcessor, renderMarkdownBlock, splitMarkdownBlocks };
@@ -284,15 +284,23 @@ var extractTextContent = function extractTextContent1(children) {
284
284
  useEffect(function() {
285
285
  // 延迟一帧渲染图表,确保容器已挂载到 DOM 且有正确的宽度
286
286
  // 解决 recharts ResponsiveContainer 在零宽容器中崩溃的问题
287
+ var cancelled = false;
287
288
  var raf = requestAnimationFrame(function() {
289
+ if (cancelled) {
290
+ return;
291
+ }
288
292
  setMounted(true);
289
293
  });
290
294
  return function() {
291
- return cancelAnimationFrame(raf);
295
+ cancelled = true;
296
+ cancelAnimationFrame(raf);
292
297
  };
293
298
  }, []);
294
299
  useEffect(function() {
295
300
  if (!mounted) return;
301
+ if (typeof window === 'undefined') {
302
+ return;
303
+ }
296
304
  var updateWidth = function updateWidth() {
297
305
  var _containerRef_current;
298
306
  var width = ((_containerRef_current = containerRef.current) === null || _containerRef_current === void 0 ? void 0 : _containerRef_current.clientWidth) || 400;
@@ -1,7 +1,10 @@
1
1
  import React from 'react';
2
+ import type { MarkdownEditorProps } from '../../MarkdownEditor/types';
2
3
  import type { RendererBlockProps } from '../types';
3
4
  /**
4
5
  * 代码块渲染器——复用 MarkdownEditor 的 CodeContainer 和样式体系。
5
6
  * 不依赖 Slate 上下文,提供与 CodeRenderer readonly 模式一致的视觉效果。
6
7
  */
7
- export declare const CodeBlockRenderer: React.FC<RendererBlockProps>;
8
+ export declare const CodeBlockRenderer: React.FC<RendererBlockProps & {
9
+ editorCodeProps?: MarkdownEditorProps['codeProps'];
10
+ }>;
@@ -52,6 +52,7 @@ import { I18nContext } from "../../I18n";
52
52
  import { CodeContainer } from "../../Plugins/code/components/CodeContainer";
53
53
  import { LoadImage } from "../../Plugins/code/components/LoadImage";
54
54
  import { langIconMap } from "../../Plugins/code/langIconMap";
55
+ import { debugInfo } from "../../Utils/debugUtils";
55
56
  var extractTextContent = function extractTextContent1(children) {
56
57
  var _children_props;
57
58
  if (typeof children === 'string') return children;
@@ -67,8 +68,10 @@ var extractTextContent = function extractTextContent1(children) {
67
68
  * 不依赖 Slate 上下文,提供与 CodeRenderer readonly 模式一致的视觉效果。
68
69
  */ export var CodeBlockRenderer = function CodeBlockRenderer(props) {
69
70
  var _i18n_locale, _i18n_locale1, _i18n_locale2;
70
- var language = props.language, children = props.children;
71
- var _useState = _sliced_to_array(useState('github'), 2), theme = _useState[0], setTheme = _useState[1];
71
+ var language = props.language, children = props.children, editorCodeProps = props.editorCodeProps;
72
+ var _useState = _sliced_to_array(useState(function() {
73
+ return (editorCodeProps === null || editorCodeProps === void 0 ? void 0 : editorCodeProps.theme) || 'github';
74
+ }), 2), theme = _useState[0], setTheme = _useState[1];
72
75
  var _useState1 = _sliced_to_array(useState(true), 2), isExpanded = _useState1[0], setIsExpanded = _useState1[1];
73
76
  var i18n = useContext(I18nContext);
74
77
  var code = useMemo(function() {
@@ -101,7 +104,7 @@ var extractTextContent = function extractTextContent1(children) {
101
104
  code
102
105
  ]);
103
106
  var langIcon = langIconMap.get((language === null || language === void 0 ? void 0 : language.toLowerCase()) || '');
104
- return /*#__PURE__*/ React.createElement(CodeContainer, {
107
+ var defaultDom = /*#__PURE__*/ React.createElement(CodeContainer, {
105
108
  element: fakeElement,
106
109
  showBorder: false,
107
110
  hide: false,
@@ -214,5 +217,26 @@ var extractTextContent = function extractTextContent1(children) {
214
217
  }, /*#__PURE__*/ React.createElement("code", {
215
218
  className: language ? "language-".concat(language) : undefined
216
219
  }, children))));
220
+ var customRender = editorCodeProps === null || editorCodeProps === void 0 ? void 0 : editorCodeProps.render;
221
+ if (!customRender) {
222
+ return defaultDom;
223
+ }
224
+ try {
225
+ var renderElementProps = {
226
+ attributes: {},
227
+ children: null,
228
+ element: fakeElement
229
+ };
230
+ var rendered = customRender(renderElementProps, defaultDom, editorCodeProps);
231
+ if (rendered === undefined) {
232
+ return defaultDom;
233
+ }
234
+ return rendered;
235
+ } catch (error) {
236
+ debugInfo('CodeBlockRenderer - codeProps.render 异常,回退默认', {
237
+ error: (error === null || error === void 0 ? void 0 : error.message) || String(error)
238
+ });
239
+ return defaultDom;
240
+ }
217
241
  };
218
242
  CodeBlockRenderer.displayName = 'CodeBlockRenderer';
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { MarkdownEditorProps } from '../../MarkdownEditor/types';
2
3
  import type { RendererBlockProps } from '../types';
3
4
  /**
4
5
  * Schema / Apaasify 渲染器
@@ -12,4 +13,5 @@ import type { RendererBlockProps } from '../types';
12
13
  */
13
14
  export declare const SchemaBlockRenderer: React.FC<RendererBlockProps & {
14
15
  apaasifyRender?: (value: any) => React.ReactNode;
16
+ editorCodeProps?: MarkdownEditorProps['codeProps'];
15
17
  }>;
@@ -1,6 +1,7 @@
1
1
  import React, { useMemo } from "react";
2
2
  import partialParse from "../../MarkdownEditor/editor/parser/json-parse";
3
3
  import { SchemaRenderer } from "../../Schema";
4
+ import { debugInfo } from "../../Utils/debugUtils";
4
5
  var extractTextContent = function extractTextContent1(children) {
5
6
  var _children_props;
6
7
  if (typeof children === 'string') return children;
@@ -34,15 +35,38 @@ var extractTextContent = function extractTextContent1(children) {
34
35
  * - ```apassify → 同 apaasify(兼容旧版)
35
36
  * - ```agentar-card → SchemaRenderer
36
37
  */ export var SchemaBlockRenderer = function SchemaBlockRenderer(props) {
37
- var children = props.children, language = props.language, apaasifyRender = props.apaasifyRender;
38
+ var children = props.children, language = props.language, apaasifyRender = props.apaasifyRender, editorCodeProps = props.editorCodeProps;
38
39
  var code = extractTextContent(children);
39
40
  var schemaValue = useMemo(function() {
40
41
  return parseSchemaValue(code);
41
42
  }, [
42
43
  code
43
44
  ]);
45
+ var applyCodeRender = function applyCodeRender(defaultDom, valueForElement) {
46
+ var customRender = editorCodeProps === null || editorCodeProps === void 0 ? void 0 : editorCodeProps.render;
47
+ if (!customRender) return defaultDom;
48
+ var slateLike = {
49
+ attributes: {},
50
+ children: null,
51
+ element: {
52
+ type: language === 'agentar-card' ? 'card' : 'schema',
53
+ value: valueForElement,
54
+ language: language
55
+ }
56
+ };
57
+ try {
58
+ var rendered = customRender(slateLike, defaultDom, editorCodeProps);
59
+ if (rendered === undefined) return defaultDom;
60
+ return rendered;
61
+ } catch (error) {
62
+ debugInfo('SchemaBlockRenderer - codeProps.render 异常,回退默认', {
63
+ error: (error === null || error === void 0 ? void 0 : error.message) || String(error)
64
+ });
65
+ return defaultDom;
66
+ }
67
+ };
44
68
  if (!schemaValue) {
45
- return /*#__PURE__*/ React.createElement("pre", {
69
+ var fallbackDom = /*#__PURE__*/ React.createElement("pre", {
46
70
  "data-testid": "schema-fallback",
47
71
  style: {
48
72
  background: 'rgb(242, 241, 241)',
@@ -59,11 +83,12 @@ var extractTextContent = function extractTextContent1(children) {
59
83
  wordWrap: 'break-word'
60
84
  }
61
85
  }, /*#__PURE__*/ React.createElement("code", null, code));
86
+ return applyCodeRender(fallbackDom, code);
62
87
  }
63
88
  if (apaasifyRender) {
64
89
  var rendered = apaasifyRender(schemaValue);
65
90
  if (rendered !== undefined) {
66
- return /*#__PURE__*/ React.createElement("div", {
91
+ var apaasifyDom = /*#__PURE__*/ React.createElement("div", {
67
92
  "data-testid": "schema-container",
68
93
  contentEditable: false,
69
94
  style: {
@@ -82,10 +107,11 @@ var extractTextContent = function extractTextContent1(children) {
82
107
  overflow: 'hidden'
83
108
  }
84
109
  }, JSON.stringify(schemaValue, null, 2)));
110
+ return applyCodeRender(apaasifyDom, schemaValue);
85
111
  }
86
112
  }
87
113
  if (language === 'agentar-card') {
88
- return /*#__PURE__*/ React.createElement("div", {
114
+ var cardDom = /*#__PURE__*/ React.createElement("div", {
89
115
  "data-testid": "agentar-card-container",
90
116
  style: {
91
117
  padding: '0.5em'
@@ -98,8 +124,9 @@ var extractTextContent = function extractTextContent1(children) {
98
124
  debug: false,
99
125
  fallbackContent: null
100
126
  }));
127
+ return applyCodeRender(cardDom, schemaValue);
101
128
  }
102
- return /*#__PURE__*/ React.createElement("div", {
129
+ var schemaDom = /*#__PURE__*/ React.createElement("div", {
103
130
  "data-testid": "schema-renderer",
104
131
  style: {
105
132
  padding: '0.5em'
@@ -111,5 +138,6 @@ var extractTextContent = function extractTextContent1(children) {
111
138
  debug: false,
112
139
  fallbackContent: null
113
140
  }));
141
+ return applyCodeRender(schemaDom, schemaValue);
114
142
  };
115
143
  SchemaBlockRenderer.displayName = 'SchemaBlockRenderer';
@@ -1,15 +1,13 @@
1
1
  import type { Processor } from 'unified';
2
2
  import React from 'react';
3
3
  export interface MarkdownBlockPieceProps {
4
- /** 末块为 tail(生长中);一旦其后出现新块,同一段内容变为 sealed,保持同一 React key 可避免重组件卸载 */
5
4
  variant: 'sealed' | 'tail';
6
5
  blockSource: string;
7
6
  processor: Processor;
8
7
  components: Record<string, any>;
9
- /** 仅末块且处于流式模式时为 true,用于节流与末段动画 */
10
8
  streaming: boolean;
11
9
  }
12
10
  /**
13
- * 统一的块级渲染:封版与末块使用同一组件类型;按 blockSource 缓存解析结果引用,使 tail→sealed 时与旧 Map 缓存一样复用同一棵 React 子树。
11
+ * 块级渲染单元:sealed 块缓存不动,tail 块节流重解析 + 闪烁光标。
14
12
  */
15
13
  export declare const MarkdownBlockPiece: React.NamedExoticComponent<MarkdownBlockPieceProps>;
@@ -1,49 +1,37 @@
1
1
  import React, { memo, useMemo, useRef } from "react";
2
2
  import { renderMarkdownBlock } from "../markdownReactShared";
3
3
  import { StreamingAnimationContext } from "../StreamingAnimationContext";
4
+ import { StreamingCursor } from "../StreamingCursor";
4
5
  import { shouldReparseLastBlock } from "./lastBlockThrottle";
5
6
  /**
6
- * 统一的块级渲染:封版与末块使用同一组件类型;按 blockSource 缓存解析结果引用,使 tail→sealed 时与旧 Map 缓存一样复用同一棵 React 子树。
7
+ * 块级渲染单元:sealed 块缓存不动,tail 块节流重解析 + 闪烁光标。
7
8
  */ export var MarkdownBlockPiece = /*#__PURE__*/ memo(function MarkdownBlockPiece(param) {
8
9
  var variant = param.variant, blockSource = param.blockSource, processor = param.processor, components = param.components, streaming = param.streaming;
9
10
  var lastParsedRef = useRef(null);
10
- /** 完整 parse 结果缓存:键为 block 源串,供 sealed 与 tail 晋升时复用同一引用 */ var parseBySourceRef = useRef(new Map());
11
+ var cacheRef = useRef(new Map());
11
12
  var node = useMemo(function() {
12
- var cached = parseBySourceRef.current.get(blockSource);
13
- if (cached && variant === 'sealed') {
14
- return cached;
15
- }
16
- if (variant === 'sealed') {
17
- var el = renderMarkdownBlock(blockSource, processor, components, {
18
- markStreamingTailParagraph: false
19
- });
20
- parseBySourceRef.current.set(blockSource, el);
21
- return el;
22
- }
23
- if (!streaming) {
24
- var el1 = renderMarkdownBlock(blockSource, processor, components, {
25
- markStreamingTailParagraph: false
26
- });
27
- parseBySourceRef.current.set(blockSource, el1);
28
- lastParsedRef.current = {
13
+ var cached = cacheRef.current.get(blockSource);
14
+ if (cached && variant === 'sealed') return cached;
15
+ if (variant === 'sealed' || !streaming) {
16
+ var el = renderMarkdownBlock(blockSource, processor, components);
17
+ cacheRef.current.set(blockSource, el);
18
+ if (variant === 'tail') lastParsedRef.current = {
29
19
  source: blockSource,
30
- node: el1
20
+ node: el
31
21
  };
32
- return el1;
22
+ return el;
33
23
  }
34
24
  var prev = lastParsedRef.current;
35
25
  if (prev && !shouldReparseLastBlock(prev.source, blockSource, true)) {
36
26
  return prev.node;
37
27
  }
38
- var el2 = renderMarkdownBlock(blockSource, processor, components, {
39
- markStreamingTailParagraph: true
40
- });
41
- parseBySourceRef.current.set(blockSource, el2);
28
+ var el1 = renderMarkdownBlock(blockSource, processor, components);
29
+ cacheRef.current.set(blockSource, el1);
42
30
  lastParsedRef.current = {
43
31
  source: blockSource,
44
- node: el2
32
+ node: el1
45
33
  };
46
- return el2;
34
+ return el1;
47
35
  }, [
48
36
  variant,
49
37
  blockSource,
@@ -56,6 +44,6 @@ import { shouldReparseLastBlock } from "./lastBlockThrottle";
56
44
  value: {
57
45
  animateBlock: animateBlock
58
46
  }
59
- }, node);
47
+ }, node, animateBlock && /*#__PURE__*/ React.createElement(StreamingCursor, null));
60
48
  });
61
49
  MarkdownBlockPiece.displayName = 'MarkdownBlockPiece';
@@ -18,12 +18,13 @@ import { shouldResetRevisionProgress } from "./revisionPolicy";
18
18
  ]);
19
19
  var prefixCls = (options === null || options === void 0 ? void 0 : options.prefixCls) || 'ant-agentic-md-editor';
20
20
  var components = useMemo(function() {
21
- return buildEditorAlignedComponents(prefixCls, (options === null || options === void 0 ? void 0 : options.components) || {}, 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, options === null || options === void 0 ? void 0 : options.eleRender);
21
+ return buildEditorAlignedComponents(prefixCls, (options === null || options === void 0 ? void 0 : options.components) || {}, 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.fncProps, options === null || options === void 0 ? void 0 : options.streamingParagraphAnimation, options === null || options === void 0 ? void 0 : options.eleRender);
22
22
  }, [
23
23
  prefixCls,
24
24
  options === null || options === void 0 ? void 0 : options.components,
25
25
  options === null || options === void 0 ? void 0 : options.streaming,
26
26
  options === null || options === void 0 ? void 0 : options.linkConfig,
27
+ options === null || options === void 0 ? void 0 : options.fncProps,
27
28
  options === null || options === void 0 ? void 0 : options.streamingParagraphAnimation,
28
29
  options === null || options === void 0 ? void 0 : options.eleRender
29
30
  ]);
@@ -42,6 +42,24 @@ export var useRendererVarStyle = function useRendererVarStyle(prefixCls) {
42
42
  transform: 'translateY(0)',
43
43
  filter: 'blur(0px)'
44
44
  }
45
+ }), _define_property(_obj, '@keyframes markdownStreamingCursorBlink', {
46
+ '0%, 100%': {
47
+ opacity: 0.9,
48
+ boxShadow: '0 0 4px currentColor'
49
+ },
50
+ '50%': {
51
+ opacity: 0,
52
+ boxShadow: '0 0 0 currentColor'
53
+ }
54
+ }), _define_property(_obj, '@keyframes markdownStreamingCursorFadeIn', {
55
+ from: {
56
+ opacity: 0,
57
+ transform: 'scaleY(0.3)'
58
+ },
59
+ to: {
60
+ opacity: 0.9,
61
+ transform: 'scaleY(1)'
62
+ }
45
63
  }), _obj;
46
64
  });
47
65
  };