@ant-design/agentic-ui 2.16.1 → 2.17.0

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.
@@ -248,7 +248,7 @@ function _ts_generator(thisArg, body) {
248
248
  }
249
249
  }
250
250
  import { BlockOutlined, DeleteFilled, ExclamationCircleOutlined, LoadingOutlined } from "@ant-design/icons";
251
- import { Image, Modal, Popover, Space } from "antd";
251
+ import { Image, Modal, Popover, Skeleton, Space } from "antd";
252
252
  import React, { useCallback, useContext, useLayoutEffect, useMemo, useRef } from "react";
253
253
  import { useDebounceFn } from "@ant-design/pro-components";
254
254
  import { Rnd } from "react-rnd";
@@ -315,7 +315,8 @@ import { getMediaType } from "../../utils/dom";
315
315
  })));
316
316
  }
317
317
  return /*#__PURE__*/ React.createElement("div", {
318
- "data-testid": "image-container"
318
+ "data-testid": "image-container",
319
+ "data-be": "image-container"
319
320
  }, /*#__PURE__*/ React.createElement(Image, _object_spread_props(_object_spread({}, props), {
320
321
  width: Number(props.width) || props.width || 400,
321
322
  onError: function() {
@@ -477,7 +478,7 @@ import { getMediaType } from "../../utils/dom";
477
478
  };
478
479
  export function EditorImage(param) {
479
480
  var element = param.element, attributes = param.attributes, children = param.children;
480
- var _state;
481
+ var _state, _element_otherProps;
481
482
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
482
483
  var _useSelStatus = _sliced_to_array(useSelStatus(element), 2), _ = _useSelStatus[0], path = _useSelStatus[1];
483
484
  var _useEditorStore = useEditorStore(), markdownEditorRef = _useEditorStore.markdownEditorRef, readonly = _useEditorStore.readonly;
@@ -550,7 +551,15 @@ export function EditorImage(param) {
550
551
  element === null || element === void 0 ? void 0 : element.url
551
552
  ]);
552
553
  var imageDom = useMemo(function() {
553
- var _state, _state1;
554
+ var _element_otherProps, _state, _state1;
555
+ // 检查是否为不完整的图片(loading 状态)
556
+ var isLoading = (element === null || element === void 0 ? void 0 : element.loading) || (element === null || element === void 0 ? void 0 : (_element_otherProps = element.otherProps) === null || _element_otherProps === void 0 ? void 0 : _element_otherProps.loading);
557
+ if (isLoading) {
558
+ // 显示 loading 状态的占位符
559
+ return /*#__PURE__*/ React.createElement(Skeleton.Image, {
560
+ active: true
561
+ });
562
+ }
554
563
  // 如果图片加载失败,显示为链接
555
564
  if (!state().loadSuccess) {
556
565
  var _state2, _state3;
@@ -622,7 +631,10 @@ export function EditorImage(param) {
622
631
  (_state = state()) === null || _state === void 0 ? void 0 : _state.url,
623
632
  readonly,
624
633
  state().selected,
625
- state().loadSuccess
634
+ state().loadSuccess,
635
+ element === null || element === void 0 ? void 0 : element.loading,
636
+ element === null || element === void 0 ? void 0 : (_element_otherProps = element.otherProps) === null || _element_otherProps === void 0 ? void 0 : _element_otherProps.loading,
637
+ element === null || element === void 0 ? void 0 : element.rawMarkdown
626
638
  ]);
627
639
  return /*#__PURE__*/ React.createElement("div", _object_spread_props(_object_spread({}, attributes), {
628
640
  "data-be": "image",
@@ -224,7 +224,7 @@ function _ts_generator(thisArg, body) {
224
224
  }
225
225
  }
226
226
  import { DeleteFilled, ExclamationCircleOutlined, EyeOutlined, LoadingOutlined } from "@ant-design/icons";
227
- import { Modal, Popover } from "antd";
227
+ import { Modal, Popover, Skeleton } from "antd";
228
228
  import React, { useCallback, useContext, useLayoutEffect, useMemo, useRef } from "react";
229
229
  import { useDebounceFn } from "@ant-design/pro-components";
230
230
  import { Rnd } from "react-rnd";
@@ -379,7 +379,7 @@ import { ImageAndError } from "./Image";
379
379
  };
380
380
  export function Media(param) {
381
381
  var element = param.element, attributes = param.attributes, children = param.children;
382
- var _state, _state1;
382
+ var _state, _element_otherProps, _state1, _element_otherProps1;
383
383
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
384
384
  var _useSelStatus = _sliced_to_array(useSelStatus(element), 2), _ = _useSelStatus[0], path = _useSelStatus[1];
385
385
  var _useEditorStore = useEditorStore(), markdownEditorRef = _useEditorStore.markdownEditorRef, readonly = _useEditorStore.readonly;
@@ -483,8 +483,16 @@ export function Media(param) {
483
483
  element === null || element === void 0 ? void 0 : element.url
484
484
  ]);
485
485
  var imageDom = useMemo(function() {
486
- var _state, _state1;
486
+ var _element_otherProps, _state, _state1;
487
487
  if (state().type !== 'image' && state().type !== 'other') return null;
488
+ // 检查是否为不完整的图片(loading 状态)
489
+ var isLoading = (element === null || element === void 0 ? void 0 : element.loading) || (element === null || element === void 0 ? void 0 : (_element_otherProps = element.otherProps) === null || _element_otherProps === void 0 ? void 0 : _element_otherProps.loading);
490
+ if (isLoading) {
491
+ // 显示 loading 状态的占位符
492
+ return /*#__PURE__*/ React.createElement(Skeleton.Image, {
493
+ active: true
494
+ });
495
+ }
488
496
  return !readonly ? /*#__PURE__*/ React.createElement(ResizeImage, {
489
497
  defaultSize: {
490
498
  width: element.width,
@@ -528,11 +536,24 @@ export function Media(param) {
528
536
  state().type,
529
537
  (_state = state()) === null || _state === void 0 ? void 0 : _state.url,
530
538
  readonly,
531
- state().selected
539
+ state().selected,
540
+ element === null || element === void 0 ? void 0 : element.loading,
541
+ element === null || element === void 0 ? void 0 : (_element_otherProps = element.otherProps) === null || _element_otherProps === void 0 ? void 0 : _element_otherProps.loading,
542
+ element === null || element === void 0 ? void 0 : element.rawMarkdown
532
543
  ]);
533
544
  var mediaElement = useMemo(function() {
545
+ var _element_otherProps, _element_otherProps1;
546
+ // 检查是否为不完整的媒体(loading 状态)
547
+ var isLoading = (element === null || element === void 0 ? void 0 : element.loading) || (element === null || element === void 0 ? void 0 : (_element_otherProps = element.otherProps) === null || _element_otherProps === void 0 ? void 0 : _element_otherProps.loading);
548
+ var rawMarkdown = (element === null || element === void 0 ? void 0 : element.rawMarkdown) || (element === null || element === void 0 ? void 0 : (_element_otherProps1 = element.otherProps) === null || _element_otherProps1 === void 0 ? void 0 : _element_otherProps1.rawMarkdown);
534
549
  if (state().type === 'video') {
535
550
  var _state;
551
+ // 如果是 loading 状态,显示 loading 占位符
552
+ if (isLoading) {
553
+ return /*#__PURE__*/ React.createElement(Skeleton.Image, {
554
+ active: true
555
+ });
556
+ }
536
557
  if (!state().loadSuccess) {
537
558
  var _state1, _state2;
538
559
  return /*#__PURE__*/ React.createElement("a", {
@@ -586,6 +607,34 @@ export function Media(param) {
586
607
  }
587
608
  if (state().type === 'audio') {
588
609
  var _state3;
610
+ // 如果是 loading 状态,显示 loading 占位符
611
+ if (isLoading) {
612
+ return /*#__PURE__*/ React.createElement("div", {
613
+ style: {
614
+ display: 'inline-flex',
615
+ alignItems: 'center',
616
+ gap: '8px',
617
+ padding: '12px 16px',
618
+ border: '1px dashed #d9d9d9',
619
+ borderRadius: '6px',
620
+ backgroundColor: '#fafafa',
621
+ minWidth: '200px',
622
+ justifyContent: 'center'
623
+ }
624
+ }, /*#__PURE__*/ React.createElement(LoadingOutlined, {
625
+ style: {
626
+ color: '#1890ff',
627
+ fontSize: '16px'
628
+ },
629
+ spin: true
630
+ }), /*#__PURE__*/ React.createElement("span", {
631
+ style: {
632
+ color: '#666',
633
+ fontSize: '13px',
634
+ wordBreak: 'break-all'
635
+ }
636
+ }, rawMarkdown || (element === null || element === void 0 ? void 0 : element.alt) || '音频加载中...'));
637
+ }
589
638
  if (!state().loadSuccess) {
590
639
  var _state4, _state5;
591
640
  return /*#__PURE__*/ React.createElement("a", {
@@ -629,7 +678,7 @@ export function Media(param) {
629
678
  }, "Your browser does not support the", /*#__PURE__*/ React.createElement("code", null, "audio"), " element.");
630
679
  }
631
680
  if (state().type === 'attachment') {
632
- var _state6, _element_alt, _element_alt1, _element_otherProps, _element_otherProps_collaborators, _element_otherProps1, _element_otherProps2;
681
+ var _state6, _element_alt, _element_alt1, _element_otherProps2, _element_otherProps_collaborators, _element_otherProps3, _element_otherProps4;
633
682
  return /*#__PURE__*/ React.createElement("div", {
634
683
  style: {
635
684
  padding: 12,
@@ -678,15 +727,15 @@ export function Media(param) {
678
727
  display: 'flex',
679
728
  justifyContent: 'space-between'
680
729
  }
681
- }, ((_element_otherProps = element.otherProps) === null || _element_otherProps === void 0 ? void 0 : _element_otherProps.collaborators) ? /*#__PURE__*/ React.createElement("div", null, /*#__PURE__*/ React.createElement(AvatarList, {
682
- displayList: ((_element_otherProps1 = element.otherProps) === null || _element_otherProps1 === void 0 ? void 0 : (_element_otherProps_collaborators = _element_otherProps1.collaborators) === null || _element_otherProps_collaborators === void 0 ? void 0 : _element_otherProps_collaborators.map(function(item) {
730
+ }, ((_element_otherProps2 = element.otherProps) === null || _element_otherProps2 === void 0 ? void 0 : _element_otherProps2.collaborators) ? /*#__PURE__*/ React.createElement("div", null, /*#__PURE__*/ React.createElement(AvatarList, {
731
+ displayList: ((_element_otherProps3 = element.otherProps) === null || _element_otherProps3 === void 0 ? void 0 : (_element_otherProps_collaborators = _element_otherProps3.collaborators) === null || _element_otherProps_collaborators === void 0 ? void 0 : _element_otherProps_collaborators.map(function(item) {
683
732
  var _Object_keys, _Object_values;
684
733
  return {
685
734
  name: (_Object_keys = Object.keys(item)) === null || _Object_keys === void 0 ? void 0 : _Object_keys.at(0),
686
735
  collaboratorNumber: ((_Object_values = Object.values(item)) === null || _Object_values === void 0 ? void 0 : _Object_values.at(0)) || 0
687
736
  };
688
737
  }).slice(0, 5)) || []
689
- })) : /*#__PURE__*/ React.createElement("div", null), ((_element_otherProps2 = element.otherProps) === null || _element_otherProps2 === void 0 ? void 0 : _element_otherProps2.updateTime) ? /*#__PURE__*/ React.createElement("div", {
738
+ })) : /*#__PURE__*/ React.createElement("div", null), ((_element_otherProps4 = element.otherProps) === null || _element_otherProps4 === void 0 ? void 0 : _element_otherProps4.updateTime) ? /*#__PURE__*/ React.createElement("div", {
690
739
  style: {
691
740
  color: 'rgba(0,0,0,0.45)',
692
741
  fontSize: 12
@@ -711,7 +760,10 @@ export function Media(param) {
711
760
  return null;
712
761
  }, [
713
762
  state().type,
714
- (_state1 = state()) === null || _state1 === void 0 ? void 0 : _state1.url
763
+ (_state1 = state()) === null || _state1 === void 0 ? void 0 : _state1.url,
764
+ element === null || element === void 0 ? void 0 : element.loading,
765
+ element === null || element === void 0 ? void 0 : (_element_otherProps1 = element.otherProps) === null || _element_otherProps1 === void 0 ? void 0 : _element_otherProps1.loading,
766
+ element === null || element === void 0 ? void 0 : element.rawMarkdown
715
767
  ]);
716
768
  return /*#__PURE__*/ React.createElement("div", attributes, /*#__PURE__*/ React.createElement("div", {
717
769
  "data-be": "media",
@@ -157,6 +157,7 @@ var INLINE_MATH_SIMPLE_NUMBER_PATTERN = new RegExp("^[+-]?\\d+(?:\\.\\d+)?".conc
157
157
  // HTML 转义和代码块检测相关的常量
158
158
  var NOT_SPACE_START = /^\S*/;
159
159
  var ENDING_NEWLINE = /\n$/;
160
+ var FENCED_CODE_REGEX = /^(`{3,}|~{3,})/;
160
161
  var shouldTreatInlineMathAsText = function(rawValue) {
161
162
  var trimmedValue = rawValue.trim();
162
163
  if (!trimmedValue) {
@@ -715,66 +716,86 @@ export var decodeURIComponentUrl = function(url) {
715
716
  'listItem',
716
717
  'blockquote'
717
718
  ].includes(parent.type)) {
718
- // 检查是否为 <think> 标签
719
- var thinkElement = findThinkElement(currentElement.value);
720
- if (thinkElement) {
721
- // <think> 标签转换为 think 类型的代码块
722
- el = {
723
- type: 'code',
724
- language: 'think',
725
- value: thinkElement.content,
719
+ // 检查是否为不完整的图片标记
720
+ var incompleteImageMatch = currentElement.value.match(/<incomplete-image\s+data-raw="([^"]+)"\s*\/?>/);
721
+ if (incompleteImageMatch) {
722
+ var rawMarkdown = decodeURIComponent(incompleteImageMatch[1]);
723
+ // 直接创建带有 loading 状态的图片节点(不通过 createMediaNode,因为 URL 为空)
724
+ el = EditorUtils.wrapperCardNode({
725
+ type: 'image',
726
+ url: '',
727
+ mediaType: 'image',
728
+ alt: rawMarkdown,
729
+ loading: true,
730
+ rawMarkdown: rawMarkdown,
726
731
  children: [
727
732
  {
728
- text: thinkElement.content
733
+ text: ''
729
734
  }
730
735
  ]
731
- };
736
+ });
732
737
  } else {
733
- // 检查是否为 <answer> 标签
734
- var answerElement = findAnswerElement(currentElement.value);
735
- if (answerElement) {
736
- // 将 <answer> 标签的内容作为普通文本
738
+ // 检查是否为 <think> 标签
739
+ var thinkElement = findThinkElement(currentElement.value);
740
+ if (thinkElement) {
741
+ // 将 <think> 标签转换为 think 类型的代码块
737
742
  el = {
738
- text: answerElement.content
743
+ type: 'code',
744
+ language: 'think',
745
+ value: thinkElement.content,
746
+ children: [
747
+ {
748
+ text: thinkElement.content
749
+ }
750
+ ]
739
751
  };
740
752
  } else {
741
- var mediaElement = findImageElement(currentElement.value);
742
- if (mediaElement) {
743
- el = createMediaNodeFromElement(mediaElement);
744
- } else if (currentElement.value === '<br/>') {
753
+ // 检查是否为 <answer> 标签
754
+ var answerElement = findAnswerElement(currentElement.value);
755
+ if (answerElement) {
756
+ // <answer> 标签的内容作为普通文本
745
757
  el = {
746
- type: 'paragraph',
747
- children: [
748
- {
749
- text: ''
750
- }
751
- ]
758
+ text: answerElement.content
752
759
  };
753
- } else if (currentElement.value.match(/^<\/(img|video|iframe)>/)) {
754
- // 如果是媒体标签的结束标签,跳过处理
755
- el = null;
756
760
  } else {
757
- // 检查是否为注释(注释需要特殊处理以提取配置)
758
- var isComment = currentElement.value.trim().startsWith('<!--') && currentElement.value.trim().endsWith('-->');
759
- // 检查是否为标准 HTML 元素或注释
760
- if (isComment || isStandardHtmlElement(currentElement.value)) {
761
- // 标准 HTML 元素或注释:按原逻辑处理
762
- el = currentElement.value.match(/<\/?(table|div|ul|li|ol|p|strong)[^\n>]*?>/) ? htmlToFragmentList(currentElement.value, '') : {
763
- type: 'code',
764
- language: 'html',
765
- render: true,
766
- value: currentElement.value,
761
+ var mediaElement = findImageElement(currentElement.value);
762
+ if (mediaElement) {
763
+ el = createMediaNodeFromElement(mediaElement);
764
+ } else if (currentElement.value === '<br/>') {
765
+ el = {
766
+ type: 'paragraph',
767
767
  children: [
768
768
  {
769
- text: currentElement.value
769
+ text: ''
770
770
  }
771
771
  ]
772
772
  };
773
+ } else if (currentElement.value.match(/^<\/(img|video|iframe)>/)) {
774
+ // 如果是媒体标签的结束标签,跳过处理
775
+ el = null;
773
776
  } else {
774
- // 非标准元素(如自定义标签):当作普通文本处理
775
- el = {
776
- text: currentElement.value
777
- };
777
+ // 检查是否为注释(注释需要特殊处理以提取配置)
778
+ var isComment = currentElement.value.trim().startsWith('<!--') && currentElement.value.trim().endsWith('-->');
779
+ // 检查是否为标准 HTML 元素或注释
780
+ if (isComment || isStandardHtmlElement(currentElement.value)) {
781
+ // 标准 HTML 元素或注释:按原逻辑处理
782
+ el = currentElement.value.match(/<\/?(table|div|ul|li|ol|p|strong)[^\n>]*?>/) ? htmlToFragmentList(currentElement.value, '') : {
783
+ type: 'code',
784
+ language: 'html',
785
+ render: true,
786
+ value: currentElement.value,
787
+ children: [
788
+ {
789
+ text: currentElement.value
790
+ }
791
+ ]
792
+ };
793
+ } else {
794
+ // 非标准元素(如自定义标签):当作普通文本处理
795
+ el = {
796
+ text: currentElement.value
797
+ };
798
+ }
778
799
  }
779
800
  }
780
801
  }
@@ -820,6 +841,25 @@ export var decodeURIComponentUrl = function(url) {
820
841
  text: answerElement.content
821
842
  };
822
843
  }
844
+ // 检查是否为不完整的图片标记
845
+ var incompleteImageMatch = currentElement.value.match(/<incomplete-image\s+data-raw="([^"]+)"\s*\/?>/);
846
+ if (incompleteImageMatch) {
847
+ var rawMarkdown = decodeURIComponent(incompleteImageMatch[1]);
848
+ // 直接创建带有 loading 状态的图片节点(不通过 createMediaNode,因为 URL 为空)
849
+ return EditorUtils.wrapperCardNode({
850
+ type: 'image',
851
+ url: '',
852
+ mediaType: 'image',
853
+ alt: rawMarkdown,
854
+ loading: true,
855
+ rawMarkdown: rawMarkdown,
856
+ children: [
857
+ {
858
+ text: ''
859
+ }
860
+ ]
861
+ });
862
+ }
823
863
  // 检查是否为非标准 HTML 元素,如果是则直接当作文本
824
864
  if (!isStandardHtmlElement(currentElement.value)) {
825
865
  return {
@@ -1653,7 +1693,9 @@ var tableRegex = /^\|.*\|\s*\n\|[-:| ]+\|/m;
1653
1693
  'menu',
1654
1694
  'menuitem',
1655
1695
  // 字体
1656
- 'font'
1696
+ 'font',
1697
+ // 自定义标签(用于流式渲染)
1698
+ 'incomplete-image'
1657
1699
  ]);
1658
1700
  /**
1659
1701
  * 检查 HTML 标签是否为标准元素
@@ -1694,6 +1736,78 @@ var tableRegex = /^\|.*\|\s*\n\|[-:| ]+\|/m;
1694
1736
  */ function preprocessThinkTags(markdown) {
1695
1737
  return preprocessSpecialTags(markdown, 'think');
1696
1738
  }
1739
+ /**
1740
+ * 检测不完整的图片标记
1741
+ * 参考 useStreaming 中的逻辑,检测类似 ![ 或 ![text]( 的不完整图片语法
1742
+ * @param markdown - 要检测的 Markdown 字符串
1743
+ * @returns 是否为不完整的图片标记
1744
+ */ function isIncompleteImage(markdown) {
1745
+ // 匹配不完整的图片语法:
1746
+ // 1. ![ 开始但还没有 ]
1747
+ // 2. ![text] 开始但还没有 (
1748
+ // 3. ![text]( 开始但还没有 )
1749
+ var incompleteImagePatterns = [
1750
+ /^!\[[^\]\r\n]{0,1000}$/,
1751
+ /^!\[[^\r\n]{0,1000}\]\(*[^)\r\n]{0,1000}$/
1752
+ ];
1753
+ return incompleteImagePatterns.some(function(pattern) {
1754
+ return pattern.test(markdown);
1755
+ });
1756
+ }
1757
+ /**
1758
+ * 预处理不完整的图片标记,将其转换为特殊的 HTML 标签
1759
+ * @param markdown - 原始 Markdown 字符串
1760
+ * @returns 处理后的 Markdown 字符串
1761
+ */ function preprocessIncompleteImages(markdown) {
1762
+ if (!markdown) return markdown;
1763
+ // 按行处理,避免在代码块中处理
1764
+ var lines = markdown.split('\n');
1765
+ var inCodeBlock = false;
1766
+ var codeBlockFence = '';
1767
+ var codeBlockFenceLen = 0;
1768
+ var processedLines = lines.map(function(line) {
1769
+ // 检测代码块开始/结束
1770
+ var fenceMatch = line.match(FENCED_CODE_REGEX);
1771
+ if (fenceMatch) {
1772
+ var currentFence = fenceMatch[1];
1773
+ var char = currentFence[0];
1774
+ var len = currentFence.length;
1775
+ if (!inCodeBlock) {
1776
+ inCodeBlock = true;
1777
+ codeBlockFence = char;
1778
+ codeBlockFenceLen = len;
1779
+ } else if (char === codeBlockFence && len >= codeBlockFenceLen) {
1780
+ inCodeBlock = false;
1781
+ codeBlockFence = '';
1782
+ codeBlockFenceLen = 0;
1783
+ }
1784
+ return line;
1785
+ }
1786
+ // 如果在代码块中,不处理
1787
+ if (inCodeBlock) {
1788
+ return line;
1789
+ }
1790
+ // 检测不完整的图片标记
1791
+ // 匹配行尾的不完整图片语法(避免匹配完整的图片)
1792
+ var trimmedLine = line.trim();
1793
+ // 如果整行就是一个不完整的图片标记
1794
+ if (isIncompleteImage(trimmedLine)) {
1795
+ var encodedRaw = encodeURIComponent(trimmedLine);
1796
+ return '<incomplete-image data-raw="'.concat(encodedRaw, '" />');
1797
+ }
1798
+ // 检测行内不完整的图片标记(在行尾)
1799
+ // 使用负向前瞻确保不是完整图片的一部分
1800
+ return line.replace(/(!\[[^\]]*\]?\(?[^)]*)$/, function(match) {
1801
+ // 检查是否是不完整的图片
1802
+ if (isIncompleteImage(match.trim())) {
1803
+ var encodedRaw = encodeURIComponent(match.trim());
1804
+ return '<incomplete-image data-raw="'.concat(encodedRaw, '" />');
1805
+ }
1806
+ return match;
1807
+ });
1808
+ });
1809
+ return processedLines.join('\n');
1810
+ }
1697
1811
  /**
1698
1812
  * 预处理所有非标准 HTML 标签,提取其内容(删除标签本身)
1699
1813
  * @param markdown - 原始 Markdown 字符串
@@ -1705,7 +1819,12 @@ var tableRegex = /^\|.*\|\s*\n\|[-:| ]+\|/m;
1705
1819
  while(hasNonStandardTags){
1706
1820
  var before = result;
1707
1821
  // 匹配所有 HTML 标签对:<tagname>content</tagname>
1822
+ // 注意:跳过 incomplete-image 标签(它是自闭合标签,需要特殊处理)
1708
1823
  result = result.replace(/<(\w+)>([\s\S]*?)<\/\1>/g, function(match, tagName, content) {
1824
+ // 保护 incomplete-image 标签(虽然它是自闭合的,但为了安全起见)
1825
+ if (tagName.toLowerCase() === 'incomplete-image') {
1826
+ return match;
1827
+ }
1709
1828
  // 检查是否为标准 HTML 元素
1710
1829
  if (STANDARD_HTML_ELEMENTS.has(tagName.toLowerCase())) {
1711
1830
  // 标准元素保持不变
@@ -1765,9 +1884,10 @@ function preprocessMarkdownTableNewlines(markdown) {
1765
1884
  * @returns 一个包含解析后的元素数组和链接信息的对象
1766
1885
  */ key: "parse",
1767
1886
  value: function parse(md) {
1768
- // 先预处理 <think> 标签,再预处理其他非标准 HTML 标签,最后处理表格换行
1887
+ // 先预处理 <think> 标签,再预处理不完整的图片,然后预处理其他非标准 HTML 标签,最后处理表格换行
1769
1888
  var thinkProcessed = preprocessThinkTags(md || '');
1770
- var nonStandardProcessed = preprocessNonStandardHtmlTags(thinkProcessed);
1889
+ var incompleteImageProcessed = preprocessIncompleteImages(thinkProcessed);
1890
+ var nonStandardProcessed = preprocessNonStandardHtmlTags(incompleteImageProcessed);
1771
1891
  var processedMarkdown = mdastParser.parse(preprocessMarkdownTableNewlines(nonStandardProcessed));
1772
1892
  var markdownRoot = processedMarkdown.children;
1773
1893
  // 使用类的配置和插件,通过 this 访问
@@ -402,6 +402,11 @@ var genStyle = function(token) {
402
402
  backgroundColor: 'var(--color-gray-control-fill-secondary)'
403
403
  }
404
404
  },
405
+ '[data-be="media-container"], [data-be="image-container"]': {
406
+ display: 'flex',
407
+ minWidth: 0,
408
+ maxWidth: '100%'
409
+ },
405
410
  '@media screen and (max-width: 600px)': {
406
411
  h1: {
407
412
  fontSize: '1.5em'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ant-design/agentic-ui",
3
- "version": "2.16.1",
3
+ "version": "2.17.0",
4
4
  "description": "面向智能体的 UI 组件库,提供多步推理可视化、工具调用展示、任务执行协同等 Agentic UI 能力",
5
5
  "repository": "git@github.com:ant-design/agentic-ui.git",
6
6
  "license": "MIT",