@ant-design/agentic-ui 2.30.14 → 2.30.17

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 (32) hide show
  1. package/dist/Bubble/AIBubble.js +3 -2
  2. package/dist/Bubble/ContentFilemapView.d.ts +2 -0
  3. package/dist/Bubble/ContentFilemapView.js +9 -6
  4. package/dist/Bubble/MessagesContent/index.js +7 -7
  5. package/dist/Bubble/UserBubble.js +2 -1
  6. package/dist/Hooks/useLanguage.d.ts +3 -1
  7. package/dist/I18n/locales.d.ts +3 -1
  8. package/dist/I18n/locales.js +8 -4
  9. package/dist/MarkdownEditor/editor/elements/Code/ReadonlyCode.js +1 -1
  10. package/dist/MarkdownEditor/editor/elements/Code/index.js +1 -1
  11. package/dist/MarkdownInputField/AttachmentButton/AttachmentButtonPopover.d.ts +1 -6
  12. package/dist/MarkdownInputField/AttachmentButton/AttachmentButtonPopover.js +2 -13
  13. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +2 -1
  14. package/dist/MarkdownInputField/AttachmentButton/index.d.ts +30 -0
  15. package/dist/MarkdownInputField/AttachmentButton/index.js +22 -6
  16. package/dist/MarkdownInputField/AttachmentButton/utils.d.ts +3 -6
  17. package/dist/MarkdownInputField/FileMapView/index.js +1 -7
  18. package/dist/MarkdownInputField/FileMapView/style.js +1 -2
  19. package/dist/MarkdownInputField/FileUploadManager/index.js +36 -21
  20. package/dist/MarkdownInputField/MarkdownInputField.js +18 -6
  21. package/dist/MarkdownInputField/SendActions/index.js +2 -2
  22. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.d.ts +1 -0
  23. package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.js +21 -0
  24. package/dist/MarkdownInputField/style.js +26 -2
  25. package/dist/MarkdownInputField/types/MarkdownInputFieldProps.d.ts +4 -4
  26. package/dist/MarkdownInputField/types/MarkdownInputFieldProps.js +1 -1
  27. package/dist/Plugins/chart/ChartRender.js +3 -1
  28. package/dist/Plugins/chart/DonutChart/index.js +1 -1
  29. package/dist/Plugins/chart/components/ChartContainer/ChartErrorBoundary.d.ts +6 -2
  30. package/dist/Workspace/File/FileComponent.js +178 -103
  31. package/dist/Workspace/File/style.js +20 -0
  32. package/package.json +1 -1
@@ -274,7 +274,7 @@ var getTaskList = function getTaskList(originData) {
274
274
  * ```
275
275
  */ export var AIBubble = /*#__PURE__*/ memo(function(props) {
276
276
  var _ref, _messageDisplayKeyRef_current, _props_readonly;
277
- 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;
277
+ var _props_originData, _props_originData1, _props_originData2, _props_originData3, _props_originData4, _props_originData5, _props_bubbleRenderConfig, _props_originData_fileMap, _props_originData6, _props_markdownRenderConfig, _props_bubbleRenderConfig1, _props_styles, _props_bubbleRenderConfig2, _bubbleRenderConfig_render;
278
278
  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;
279
279
  var _React_useState = _sliced_to_array(React.useState(false), 2), hidePadding = _React_useState[0], setHidePadding = _React_useState[1];
280
280
  var messageDisplayKeyRef = useRef(null);
@@ -318,7 +318,7 @@ var getTaskList = function getTaskList(originData) {
318
318
  }, [
319
319
  rawContent
320
320
  ]), filemapBlocks = _useMemo.blocks, strippedContent = _useMemo.stripped;
321
- var contentForDisplay = filemapBlocks.length > 0 ? strippedContent : rawContent;
321
+ var contentForDisplay = filemapBlocks.length > 0 ? strippedContent : typeof rawContent === 'string' ? rawContent : strippedContent;
322
322
  var messageContent = /*#__PURE__*/ React.createElement(BubbleMessageDisplay, {
323
323
  markdownRenderConfig: props.markdownRenderConfig,
324
324
  docListProps: props.docListProps,
@@ -415,6 +415,7 @@ var getTaskList = function getTaskList(originData) {
415
415
  blocks: filemapBlocks,
416
416
  fileViewConfig: props.fileViewConfig,
417
417
  fileViewEvents: props.fileViewEvents,
418
+ fileMapConfig: (_props_markdownRenderConfig = props.markdownRenderConfig) === null || _props_markdownRenderConfig === void 0 ? void 0 : _props_markdownRenderConfig.fileMapConfig,
418
419
  placement: placement
419
420
  }))));
420
421
  if ((bubbleRenderConfig === null || bubbleRenderConfig === void 0 ? void 0 : bubbleRenderConfig.render) === false) return null;
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { FileMapConfig } from '../MarkdownRenderer/types';
2
3
  import type { FilemapBlock } from './extractFilemapBlocks';
3
4
  import type { BubbleProps } from './type';
4
5
  /**
@@ -9,6 +10,7 @@ export declare const ContentFilemapView: React.FC<{
9
10
  blocks: FilemapBlock[];
10
11
  fileViewConfig?: BubbleProps['fileViewConfig'];
11
12
  fileViewEvents?: BubbleProps['fileViewEvents'];
13
+ fileMapConfig?: FileMapConfig;
12
14
  placement?: 'left' | 'right';
13
15
  style?: React.CSSProperties;
14
16
  }>;
@@ -15,16 +15,18 @@ var parseBody = function parseBody(body) {
15
15
  }
16
16
  };
17
17
  var FilemapItem = function FilemapItem(param) {
18
- var body = param.body, fileViewConfig = param.fileViewConfig, fileViewEvents = param.fileViewEvents, placement = param.placement;
18
+ var body = param.body, fileViewConfig = param.fileViewConfig, fileViewEvents = param.fileViewEvents, fileMapConfig = param.fileMapConfig, placement = param.placement;
19
+ var _ref, _ref1, _ref2;
19
20
  var parsed = useMemo(function() {
20
21
  return parseBody(body);
21
22
  }, [
22
23
  body
23
24
  ]);
24
25
  var _useMemo = useMemo(function() {
25
- return normalizeFileMapPropsFromJson(parsed);
26
+ return normalizeFileMapPropsFromJson(parsed, fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.normalizeFile);
26
27
  }, [
27
- parsed
28
+ parsed,
29
+ fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.normalizeFile
28
30
  ]), fileList = _useMemo.fileList, className = _useMemo.className;
29
31
  var fileMap = useMemo(function() {
30
32
  return new Map(fileList.map(function(f) {
@@ -65,9 +67,9 @@ var FilemapItem = function FilemapItem(param) {
65
67
  className: className !== null && className !== void 0 ? className : fileViewConfig === null || fileViewConfig === void 0 ? void 0 : fileViewConfig.className,
66
68
  style: fileViewConfig === null || fileViewConfig === void 0 ? void 0 : fileViewConfig.style,
67
69
  placement: placement,
68
- onPreview: events === null || events === void 0 ? void 0 : events.onPreview,
70
+ onPreview: (_ref = (_ref1 = events === null || events === void 0 ? void 0 : events.onPreview) !== null && _ref1 !== void 0 ? _ref1 : fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.onPreview) !== null && _ref !== void 0 ? _ref : defaultHandlers.onPreview,
69
71
  onDownload: events === null || events === void 0 ? void 0 : events.onDownload,
70
- itemRender: fileViewConfig === null || fileViewConfig === void 0 ? void 0 : fileViewConfig.itemRender,
72
+ itemRender: (_ref2 = fileViewConfig === null || fileViewConfig === void 0 ? void 0 : fileViewConfig.itemRender) !== null && _ref2 !== void 0 ? _ref2 : fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.itemRender,
71
73
  maxDisplayCount: fileViewConfig === null || fileViewConfig === void 0 ? void 0 : fileViewConfig.maxDisplayCount,
72
74
  showMoreButton: fileViewConfig === null || fileViewConfig === void 0 ? void 0 : fileViewConfig.showMoreButton,
73
75
  customSlot: fileViewConfig === null || fileViewConfig === void 0 ? void 0 : fileViewConfig.customSlot,
@@ -78,7 +80,7 @@ var FilemapItem = function FilemapItem(param) {
78
80
  * 将从 markdown content 中提取出的 agentic-ui-filemap 块渲染为 FileMapView 列表。
79
81
  * 渲染在气泡内容框外部,避免图片被包在带样式的气泡背景里。
80
82
  */ export var ContentFilemapView = function ContentFilemapView(param) {
81
- var blocks = param.blocks, fileViewConfig = param.fileViewConfig, fileViewEvents = param.fileViewEvents, placement = param.placement, style = param.style;
83
+ var blocks = param.blocks, fileViewConfig = param.fileViewConfig, fileViewEvents = param.fileViewEvents, fileMapConfig = param.fileMapConfig, placement = param.placement, style = param.style;
82
84
  if (blocks.length === 0) return null;
83
85
  return /*#__PURE__*/ React.createElement("div", {
84
86
  style: style,
@@ -89,6 +91,7 @@ var FilemapItem = function FilemapItem(param) {
89
91
  body: block.body,
90
92
  fileViewConfig: fileViewConfig,
91
93
  fileViewEvents: fileViewEvents,
94
+ fileMapConfig: fileMapConfig,
92
95
  placement: placement
93
96
  });
94
97
  }));
@@ -370,7 +370,7 @@ var THINKING_DOT_INDICES = [
370
370
  contentAfterDom
371
371
  ]);
372
372
  var messageContent = useMemo(function() {
373
- var _props_originData, _props_bubbleRenderConfig, _props_bubbleRenderConfig1, _props_bubbleRenderConfig2, _props_bubbleRenderConfig3, _props_bubbleRenderConfig_extraRender, _props_bubbleRenderConfig4, _props_originData_extra_tags_includes, _props_originData_extra_tags, _props_originData_extra, _props_originData1, _props_originData2, _props_originData_extra1, _props_originData3, _props_originData_extra2, _props_originData4, _props_originData5, _props_originData_extra3, _props_originData6, _props_docListProps, _props_originData7, _props_markdownRenderConfig, _props_originData8, _props_originData_extra4, _props_originData9, _props_originData10, _props_originData11;
373
+ var _props_originData, _props_bubbleRenderConfig, _props_bubbleRenderConfig1, _props_bubbleRenderConfig2, _props_bubbleRenderConfig3, _props_bubbleRenderConfig_extraRender, _props_bubbleRenderConfig4, _props_originData_extra_tags_includes, _props_originData_extra_tags, _props_originData_extra, _props_originData1, _props_originData2, _props_originData_extra1, _props_originData3, _props_originData_extra2, _props_originData4, _props_originData5, _props_originData_extra3, _props_originData6, _props_docListProps, _props_originData7, _props_markdownRenderConfig, _props_originData8, _props_originData_extra4, _props_originData9;
374
374
  if (content === LOADING_FLAT || !((_props_originData = props.originData) === null || _props_originData === void 0 ? void 0 : _props_originData.isFinished) && !content) {
375
375
  var _context_thoughtChain;
376
376
  if ((context === null || context === void 0 ? void 0 : (_context_thoughtChain = context.thoughtChain) === null || _context_thoughtChain === void 0 ? void 0 : _context_thoughtChain.alwaysRender) !== true) {
@@ -539,7 +539,7 @@ var THINKING_DOT_INDICES = [
539
539
  }, beforeContent, content, afterContent, extra));
540
540
  }
541
541
  if (content === '...' || props.placement !== 'left' || (props === null || props === void 0 ? void 0 : (_props_originData1 = props.originData) === null || _props_originData1 === void 0 ? void 0 : (_props_originData_extra = _props_originData1.extra) === null || _props_originData_extra === void 0 ? void 0 : (_props_originData_extra_tags = _props_originData_extra.tags) === null || _props_originData_extra_tags === void 0 ? void 0 : (_props_originData_extra_tags_includes = _props_originData_extra_tags.includes) === null || _props_originData_extra_tags_includes === void 0 ? void 0 : _props_originData_extra_tags_includes.call(_props_originData_extra_tags, 'REJECT_TO_ANSWER')) || ((_props_originData2 = props.originData) === null || _props_originData2 === void 0 ? void 0 : _props_originData2.role) === 'bot') {
542
- var _props_originData12, _props_originData13;
542
+ var _props_originData10;
543
543
  return wrapSSR(/*#__PURE__*/ React.createElement("div", {
544
544
  className: classNames('agent-item-default-content', "".concat(baseChatCls, "-messages-content-message"), hashId),
545
545
  "data-testid": "message-box-content",
@@ -550,14 +550,14 @@ var THINKING_DOT_INDICES = [
550
550
  placement: props.placement,
551
551
  markdownRenderConfig: props.markdownRenderConfig,
552
552
  isFinished: true,
553
- style: ((_props_originData12 = props.originData) === null || _props_originData12 === void 0 ? void 0 : _props_originData12.role) === 'bot' ? {} : {
553
+ style: ((_props_originData10 = props.originData) === null || _props_originData10 === void 0 ? void 0 : _props_originData10.role) === 'bot' ? {} : {
554
554
  color: '#343A45'
555
555
  } // 使用类名方式需要传递className,这里保留style以兼容现有API
556
556
  ,
557
557
  extra: extra,
558
558
  typing: false,
559
559
  originData: props.originData,
560
- content: (_props_originData13 = props.originData) === null || _props_originData13 === void 0 ? void 0 : _props_originData13.content
560
+ content: content
561
561
  })));
562
562
  }
563
563
  // answerStatus= 'EXCEPTION'时 一定是异常情况
@@ -576,7 +576,7 @@ var THINKING_DOT_INDICES = [
576
576
  var _item_output_chunks, _item_output;
577
577
  return ((item === null || item === void 0 ? void 0 : (_item_output = item.output) === null || _item_output === void 0 ? void 0 : (_item_output_chunks = _item_output.chunks) === null || _item_output_chunks === void 0 ? void 0 : _item_output_chunks.length) || 0) > 0;
578
578
  })) && ((_props_docListProps = props.docListProps) === null || _props_docListProps === void 0 ? void 0 : _props_docListProps.enable) !== false) {
579
- var _props_docListProps1, _props_originData_extra5, _props_originData14;
579
+ var _props_docListProps1, _props_originData_extra5, _props_originData11;
580
580
  docInfoDom = /*#__PURE__*/ React.createElement(DocInfoList, _object_spread_props(_object_spread({
581
581
  options: docInfoList.map(function(item) {
582
582
  var _item_output;
@@ -585,7 +585,7 @@ var THINKING_DOT_INDICES = [
585
585
  return item;
586
586
  })
587
587
  }, props.docListProps), {
588
- reference_url_info_list: ((_props_docListProps1 = props.docListProps) === null || _props_docListProps1 === void 0 ? void 0 : _props_docListProps1.reference_url_info_list) || ((_props_originData14 = props.originData) === null || _props_originData14 === void 0 ? void 0 : (_props_originData_extra5 = _props_originData14.extra) === null || _props_originData_extra5 === void 0 ? void 0 : _props_originData_extra5.reference_url_info_list) || []
588
+ reference_url_info_list: ((_props_docListProps1 = props.docListProps) === null || _props_docListProps1 === void 0 ? void 0 : _props_docListProps1.reference_url_info_list) || ((_props_originData11 = props.originData) === null || _props_originData11 === void 0 ? void 0 : (_props_originData_extra5 = _props_originData11.extra) === null || _props_originData_extra5 === void 0 ? void 0 : _props_originData_extra5.reference_url_info_list) || []
589
589
  }));
590
590
  }
591
591
  return wrapSSR(/*#__PURE__*/ React.createElement(MarkdownPreview, {
@@ -664,7 +664,7 @@ var THINKING_DOT_INDICES = [
664
664
  docListNode: docInfoDom,
665
665
  extra: isExtraNull ? null : extra,
666
666
  htmlRef: props.bubbleListRef,
667
- content: ((_props_originData8 = props.originData) === null || _props_originData8 === void 0 ? void 0 : _props_originData8.isFinished) && (props === null || props === void 0 ? void 0 : (_props_originData9 = props.originData) === null || _props_originData9 === void 0 ? void 0 : (_props_originData_extra4 = _props_originData9.extra) === null || _props_originData_extra4 === void 0 ? void 0 : _props_originData_extra4.answerStatus) === 'EXCEPTION' ? ((_props_originData10 = props.originData) === null || _props_originData10 === void 0 ? void 0 : _props_originData10.content) || (locale === null || locale === void 0 ? void 0 : locale['chat.message.generateFailed']) || '生成回答失败,请重试' : ((_props_originData11 = props.originData) === null || _props_originData11 === void 0 ? void 0 : _props_originData11.content) || '',
667
+ content: ((_props_originData8 = props.originData) === null || _props_originData8 === void 0 ? void 0 : _props_originData8.isFinished) && (props === null || props === void 0 ? void 0 : (_props_originData9 = props.originData) === null || _props_originData9 === void 0 ? void 0 : (_props_originData_extra4 = _props_originData9.extra) === null || _props_originData_extra4 === void 0 ? void 0 : _props_originData_extra4.answerStatus) === 'EXCEPTION' ? content || (locale === null || locale === void 0 ? void 0 : locale['chat.message.generateFailed']) || '生成回答失败,请重试' : content || '',
668
668
  originData: props.originData
669
669
  }));
670
670
  }, [
@@ -149,7 +149,7 @@ var getContentStyle = function getContentStyle(standalone, customStyle) {
149
149
  * ```
150
150
  */ export var UserBubble = /*#__PURE__*/ memo(function(props) {
151
151
  var _props_readonly;
152
- var _originData_fileMap, _props_bubbleRenderConfig, _props_styles, _props_bubbleRenderConfig1, _bubbleRenderConfig_render;
152
+ var _originData_fileMap, _props_markdownRenderConfig, _props_bubbleRenderConfig, _props_styles, _props_bubbleRenderConfig1, _bubbleRenderConfig_render;
153
153
  var className = props.className, style = props.style, bubbleRenderConfig = props.bubbleRenderConfig, classNames = props.classNames, styles = props.styles, originData = props.originData, quote = props.quote;
154
154
  var _React_useState = _sliced_to_array(React.useState(false), 2), hidePadding = _React_useState[0], setHidePadding = _React_useState[1];
155
155
  var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
@@ -257,6 +257,7 @@ var getContentStyle = function getContentStyle(standalone, customStyle) {
257
257
  blocks: filemapBlocks,
258
258
  fileViewConfig: props.fileViewConfig,
259
259
  fileViewEvents: props.fileViewEvents,
260
+ fileMapConfig: (_props_markdownRenderConfig = props.markdownRenderConfig) === null || _props_markdownRenderConfig === void 0 ? void 0 : _props_markdownRenderConfig.fileMapConfig,
260
261
  placement: placement,
261
262
  style: {
262
263
  alignSelf: 'flex-end'
@@ -307,6 +307,8 @@ export declare function useLanguage(): {
307
307
  'workspace.fileProcessError': string;
308
308
  'workspace.download': string;
309
309
  'workspace.empty': string;
310
+ 'workspace.file.showMore': string;
311
+ 'workspace.file.showMoreFiles': string;
310
312
  'workspace.title': string;
311
313
  'workspace.searchPlaceholder': string;
312
314
  'workspace.noResultsFor': string;
@@ -351,7 +353,6 @@ export declare function useLanguage(): {
351
353
  'suggestion.followUp': string;
352
354
  'input.fileUpload': string;
353
355
  'input.attachmentListTitle': string;
354
- 'chat.fileMapTitle': string;
355
356
  'input.voiceInput': string;
356
357
  'input.voiceInputting': string;
357
358
  'input.placeholder': string;
@@ -363,6 +364,7 @@ export declare function useLanguage(): {
363
364
  'input.sendButtonTooltip.newline': string;
364
365
  'input.sendButtonTooltip.send.mod': string;
365
366
  'input.sendButtonTooltip.newline.mod': string;
367
+ 'input.typing.hint': string;
366
368
  'common.name': string;
367
369
  'common.updateTime': string;
368
370
  'common.type': string;
@@ -269,6 +269,8 @@ export declare const cnLabels: {
269
269
  'workspace.fileProcessError': string;
270
270
  'workspace.download': string;
271
271
  'workspace.empty': string;
272
+ 'workspace.file.showMore': string;
273
+ 'workspace.file.showMoreFiles': string;
272
274
  'workspace.title': string;
273
275
  'workspace.searchPlaceholder': string;
274
276
  'workspace.noResultsFor': string;
@@ -313,7 +315,6 @@ export declare const cnLabels: {
313
315
  'suggestion.followUp': string;
314
316
  'input.fileUpload': string;
315
317
  'input.attachmentListTitle': string;
316
- 'chat.fileMapTitle': string;
317
318
  'input.voiceInput': string;
318
319
  'input.voiceInputting': string;
319
320
  'input.placeholder': string;
@@ -325,6 +326,7 @@ export declare const cnLabels: {
325
326
  'input.sendButtonTooltip.newline': string;
326
327
  'input.sendButtonTooltip.send.mod': string;
327
328
  'input.sendButtonTooltip.newline.mod': string;
329
+ 'input.typing.hint': string;
328
330
  'common.name': string;
329
331
  'common.updateTime': string;
330
332
  'common.type': string;
@@ -281,6 +281,8 @@
281
281
  'workspace.download': '下载',
282
282
  // 新增:默认空态文案
283
283
  'workspace.empty': '暂无数据',
284
+ 'workspace.file.showMore': '查看更多(还有 ${count} 个)',
285
+ 'workspace.file.showMoreFiles': '查看更多文件',
284
286
  // 新增:Workspace 标题与搜索相关
285
287
  'workspace.title': '工作空间',
286
288
  'workspace.searchPlaceholder': '搜索文件名',
@@ -333,18 +335,18 @@
333
335
  // MarkdownInputField related
334
336
  'input.fileUpload': '文件上传',
335
337
  'input.attachmentListTitle': '上传附件',
336
- 'chat.fileMapTitle': '结果文件',
337
338
  'input.voiceInput': '语音输入',
338
339
  'input.voiceInputting': '语音输入中,点击可停止。',
339
340
  'input.placeholder': '请输入',
340
341
  'input.selectFile': '选择文件',
341
342
  'input.openGallery': '打开相册',
342
343
  'input.openFile': '打开文件',
343
- 'input.supportedFormatMessage': '每个文件不超过 ${maxSize},支持 ${extensions}等格式。',
344
+ 'input.supportedFormatMessage': '支持 ${extensions}等格式。',
344
345
  'input.sendButtonTooltip.send': '按 Enter 键发送',
345
346
  'input.sendButtonTooltip.newline': '按 Shift+Enter 键换行',
346
347
  'input.sendButtonTooltip.send.mod': '按 Cmd/Ctrl+Enter 键发送',
347
348
  'input.sendButtonTooltip.newline.mod': '按 Enter 键换行',
349
+ 'input.typing.hint': 'AI 正在回复中,请稍候...',
348
350
  // Other translations
349
351
  'common.name': '名称',
350
352
  'common.updateTime': '更新时间',
@@ -709,6 +711,8 @@
709
711
  'workspace.download': 'Download',
710
712
  // New: default empty text
711
713
  'workspace.empty': 'No data',
714
+ 'workspace.file.showMore': 'Show more (${count} remaining)',
715
+ 'workspace.file.showMoreFiles': 'Show more files',
712
716
  // New: Workspace title & search
713
717
  'workspace.title': 'Workspace',
714
718
  'workspace.searchPlaceholder': 'Search file name',
@@ -761,18 +765,18 @@
761
765
  // MarkdownInputField related
762
766
  'input.fileUpload': 'Upload attachments',
763
767
  'input.attachmentListTitle': 'Uploaded attachments',
764
- 'chat.fileMapTitle': 'Result files',
765
768
  'input.voiceInput': 'Voice input',
766
769
  'input.voiceInputting': 'Voice input in progress, click to stop.',
767
770
  'input.placeholder': 'Please input',
768
771
  'input.selectFile': 'Select File',
769
772
  'input.openGallery': 'Open Gallery',
770
773
  'input.openFile': 'Open File',
771
- 'input.supportedFormatMessage': 'Supports file upload, each file not exceeding ${maxSize}, formats such as ${extensions}.',
774
+ 'input.supportedFormatMessage': 'Supports ${extensions} formats.',
772
775
  'input.sendButtonTooltip.send': 'Press Enter to send',
773
776
  'input.sendButtonTooltip.newline': 'Press Shift+Enter for new line',
774
777
  'input.sendButtonTooltip.send.mod': 'Press Cmd/Ctrl+Enter to send',
775
778
  'input.sendButtonTooltip.newline.mod': 'Press Enter for new line',
779
+ 'input.typing.hint': 'AI is replying, please wait...',
776
780
  // Other translations
777
781
  'common.name': 'Name',
778
782
  'common.updateTime': 'Update Time',
@@ -106,7 +106,7 @@ import { debugInfo } from "../../../../Utils/debugUtils";
106
106
  // 检查代码块是否未闭合
107
107
  var isUnclosed = (element === null || element === void 0 ? void 0 : (_element_otherProps2 = element.otherProps) === null || _element_otherProps2 === void 0 ? void 0 : _element_otherProps2.finished) === false;
108
108
  return /*#__PURE__*/ React.createElement("div", _object_spread_props(_object_spread({}, attributes), {
109
- "data-is-unclosed": isUnclosed,
109
+ "data-is-unclosed": isUnclosed || undefined,
110
110
  "data-language": element === null || element === void 0 ? void 0 : element.language,
111
111
  style: (element === null || element === void 0 ? void 0 : element.language) === 'html' ? {
112
112
  display: (element === null || element === void 0 ? void 0 : (_element_otherProps3 = element.otherProps) === null || _element_otherProps3 === void 0 ? void 0 : _element_otherProps3.isConfig) ? 'none' : 'block'
@@ -85,7 +85,7 @@ export var Code = function Code(param) {
85
85
  // 检查代码块是否未闭合
86
86
  var isUnclosed = (element === null || element === void 0 ? void 0 : (_element_otherProps2 = element.otherProps) === null || _element_otherProps2 === void 0 ? void 0 : _element_otherProps2.finished) === false;
87
87
  return /*#__PURE__*/ React.createElement("div", _object_spread_props(_object_spread({}, attributes), {
88
- "data-is-unclosed": isUnclosed,
88
+ "data-is-unclosed": isUnclosed || undefined,
89
89
  "data-language": element === null || element === void 0 ? void 0 : element.language,
90
90
  style: {
91
91
  height: '240px',
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import type { LocalKeys } from '../../I18n';
3
3
  export type SupportedFormat = {
4
4
  type: string;
5
- maxSize: number;
6
5
  extensions: string[];
7
6
  icon: React.ReactNode;
8
7
  content?: React.ReactNode;
@@ -12,32 +11,28 @@ export type AttachmentButtonPopoverProps = {
12
11
  supportedFormat?: SupportedFormat;
13
12
  /** 上传图片的处理函数 */
14
13
  uploadImage?: (forGallery?: boolean) => Promise<void>;
15
- /** 国际化文案,可覆盖 I18n 上下文中的配置。支持 `input.openGallery`、`input.openFile`、`input.supportedFormatMessage`(模板变量:${maxSize}、${extensions})等 */
14
+ /** 国际化文案,可覆盖 I18n 上下文中的配置。支持 `input.openGallery`、`input.openFile`、`input.supportedFormatMessage`(模板变量:${extensions})等 */
16
15
  locale?: Partial<LocalKeys>;
17
16
  };
18
17
  export declare const SupportedFileFormats: {
19
18
  image: {
20
19
  icon: React.JSX.Element;
21
20
  type: string;
22
- maxSize: number;
23
21
  extensions: string[];
24
22
  };
25
23
  document: {
26
24
  icon: React.JSX.Element;
27
25
  type: string;
28
- maxSize: number;
29
26
  extensions: string[];
30
27
  };
31
28
  audio: {
32
29
  icon: React.JSX.Element;
33
30
  type: string;
34
- maxSize: number;
35
31
  extensions: string[];
36
32
  };
37
33
  video: {
38
34
  icon: React.JSX.Element;
39
35
  type: string;
40
- maxSize: number;
41
36
  extensions: string[];
42
37
  };
43
38
  };
@@ -77,12 +77,7 @@ import { Button, Modal, Tooltip } from "antd";
77
77
  import React, { useContext, useMemo, useState } from "react";
78
78
  import { useRefFunction } from "../../Hooks/useRefFunction";
79
79
  import { compileTemplate, I18nContext } from "../../I18n";
80
- import { isMobileDevice, isVivoOrOppoDevice, kbToSize } from "./utils";
81
- var FILE_SIZE_UNITS = {
82
- KB: 1024,
83
- MB: 1024 * 1024
84
- };
85
- var DEFAULT_MAX_SIZE = 5000;
80
+ import { isMobileDevice, isVivoOrOppoDevice } from "./utils";
86
81
  var CONTENT_STYLE = {
87
82
  fontSize: 16,
88
83
  lineHeight: '1.5em',
@@ -92,7 +87,6 @@ export var SupportedFileFormats = {
92
87
  image: {
93
88
  icon: /*#__PURE__*/ React.createElement(FileImageOutlined, null),
94
89
  type: '图片',
95
- maxSize: 10 * FILE_SIZE_UNITS.KB,
96
90
  extensions: [
97
91
  'jpg',
98
92
  'jpeg',
@@ -106,7 +100,6 @@ export var SupportedFileFormats = {
106
100
  document: {
107
101
  icon: /*#__PURE__*/ React.createElement(FileTextFilled, null),
108
102
  type: '文档',
109
- maxSize: 10 * FILE_SIZE_UNITS.KB,
110
103
  extensions: [
111
104
  'pdf',
112
105
  'markdown',
@@ -123,7 +116,6 @@ export var SupportedFileFormats = {
123
116
  audio: {
124
117
  icon: /*#__PURE__*/ React.createElement(AudioOutlined, null),
125
118
  type: '音频',
126
- maxSize: 50 * FILE_SIZE_UNITS.KB,
127
119
  extensions: [
128
120
  'mp3',
129
121
  'wav'
@@ -132,7 +124,6 @@ export var SupportedFileFormats = {
132
124
  video: {
133
125
  icon: /*#__PURE__*/ React.createElement(VideoCameraOutlined, null),
134
126
  type: '视频',
135
- maxSize: 100 * FILE_SIZE_UNITS.KB,
136
127
  extensions: [
137
128
  'mp4',
138
129
  'avi',
@@ -140,15 +131,13 @@ export var SupportedFileFormats = {
140
131
  ]
141
132
  }
142
133
  };
143
- var DEFAULT_FORMAT_MESSAGE = '每个文件不超过 ${maxSize},支持 ${extensions}等格式。';
134
+ var DEFAULT_FORMAT_MESSAGE = '支持 ${extensions}等格式。';
144
135
  var buildFormatMessage = function buildFormatMessage(format, locale) {
145
136
  var _ref;
146
137
  var _format_extensions;
147
- var maxSize = kbToSize(format.maxSize || DEFAULT_MAX_SIZE);
148
138
  var extensions = ((_format_extensions = format.extensions) === null || _format_extensions === void 0 ? void 0 : _format_extensions.join(', ')) || '';
149
139
  var template = (_ref = locale === null || locale === void 0 ? void 0 : locale['input.supportedFormatMessage']) !== null && _ref !== void 0 ? _ref : DEFAULT_FORMAT_MESSAGE;
150
140
  return compileTemplate(template, {
151
- maxSize: maxSize,
152
141
  extensions: extensions
153
142
  });
154
143
  };
@@ -122,7 +122,8 @@ export var AttachmentFileListItem = function AttachmentFileListItem(param) {
122
122
  onDelete(file);
123
123
  };
124
124
  // 有 status 但无 url/previewUrl:文件内容未拿到,展示大小与格式占位块
125
- if (isFileMetaPlaceholderState(file)) {
125
+ // 注意:error 状态不走占位符,直接在下面的 file-item 中展示失败 UI
126
+ if (!isErrorStatus && isFileMetaPlaceholderState(file)) {
126
127
  return /*#__PURE__*/ React.createElement(FileMetaPlaceholder, {
127
128
  file: file,
128
129
  className: className
@@ -48,6 +48,21 @@ export type AttachmentButtonProps = {
48
48
  currentCount: number;
49
49
  selectedCount: number;
50
50
  }) => void;
51
+ /** 文件超出 maxFileSize 大小限制时的回调 */
52
+ onExceedMaxSize?: (info: {
53
+ file: AttachmentFile;
54
+ maxSize: number;
55
+ }) => void;
56
+ /** 文件上传失败时的回调 */
57
+ onUploadError?: (info: {
58
+ file: AttachmentFile;
59
+ error: unknown;
60
+ }) => void;
61
+ /**
62
+ * 上传失败时自动将文件从列表中移除(退回),不显示错误状态
63
+ * @default false
64
+ */
65
+ removeFileOnUploadError?: boolean;
51
66
  };
52
67
  /**
53
68
  * 文件上传配置
@@ -75,6 +90,21 @@ type UploadProps = {
75
90
  currentCount: number;
76
91
  selectedCount: number;
77
92
  }) => void;
93
+ /** 文件超出 maxFileSize 大小限制时的回调 */
94
+ onExceedMaxSize?: (info: {
95
+ file: AttachmentFile;
96
+ maxSize: number;
97
+ }) => void;
98
+ /** 文件上传失败时的回调 */
99
+ onUploadError?: (info: {
100
+ file: AttachmentFile;
101
+ error: unknown;
102
+ }) => void;
103
+ /**
104
+ * 上传失败时自动将文件从列表中移除(退回),不显示错误状态
105
+ * @default false
106
+ */
107
+ removeFileOnUploadError?: boolean;
78
108
  };
79
109
  /**
80
110
  * 上传文件到服务器
@@ -259,14 +259,25 @@ var handleUploadSuccess = function handleUploadSuccess(file, url, map, props) {
259
259
  file.url = url;
260
260
  updateFileMap(map, file, props.onFileMapChange);
261
261
  };
262
- var handleUploadError = function handleUploadError(file, errorMsg, map, props) {
263
- file.status = 'error';
264
- if (errorMsg !== null) file.errorMessage = errorMsg;
265
- updateFileMap(map, file, props.onFileMapChange);
262
+ var handleUploadError = function handleUploadError(file, errorMsg, map, props, rawError) {
263
+ var _props_onUploadError;
264
+ if (props.removeFileOnUploadError) {
265
+ var _props_onFileMapChange;
266
+ if (file.uuid) map.delete(file.uuid);
267
+ (_props_onFileMapChange = props.onFileMapChange) === null || _props_onFileMapChange === void 0 ? void 0 : _props_onFileMapChange.call(props, map);
268
+ } else {
269
+ file.status = 'error';
270
+ if (errorMsg !== null) file.errorMessage = errorMsg;
271
+ updateFileMap(map, file, props.onFileMapChange);
272
+ }
273
+ (_props_onUploadError = props.onUploadError) === null || _props_onUploadError === void 0 ? void 0 : _props_onUploadError.call(props, {
274
+ file: file,
275
+ error: rawError !== null && rawError !== void 0 ? rawError : errorMsg
276
+ });
266
277
  };
267
278
  var processFile = function processFile(file, index, map, props) {
268
279
  return _async_to_generator(function() {
269
- var maxSizeKb, raw, _ref, url, isSuccess, errorMsg, error, errorMessage;
280
+ var _props_onExceedMaxSize, maxSizeKb, raw, _ref, url, isSuccess, errorMsg, error, errorMessage;
270
281
  return _ts_generator(this, function(_state) {
271
282
  switch(_state.label){
272
283
  case 0:
@@ -277,12 +288,17 @@ var processFile = function processFile(file, index, map, props) {
277
288
  case 1:
278
289
  _state.sent();
279
290
  if (!validateFileSize(file, props)) {
291
+ ;
280
292
  maxSizeKb = Math.round((props.maxFileSize || 0) / 1024);
281
293
  raw = getLocaleMessage(props.locale, 'markdownInput.fileSizeExceeded', DEFAULT_MESSAGES.fileSizeExceeded(maxSizeKb));
282
294
  file.errorMessage = raw.includes('${maxSize}') ? raw.replace(/\$\{maxSize\}/g, String(maxSizeKb)) : raw;
283
295
  file.errorCode = 'FILE_SIZE_EXCEEDED';
284
296
  file.status = 'error';
285
297
  updateFileMap(map, file, props.onFileMapChange);
298
+ (_props_onExceedMaxSize = props.onExceedMaxSize) === null || _props_onExceedMaxSize === void 0 ? void 0 : _props_onExceedMaxSize.call(props, {
299
+ file: file,
300
+ maxSize: props.maxFileSize || 0
301
+ });
286
302
  return [
287
303
  2
288
304
  ];
@@ -313,7 +329,7 @@ var processFile = function processFile(file, index, map, props) {
313
329
  case 4:
314
330
  error = _state.sent();
315
331
  errorMessage = _instanceof(error, Error) ? error.message : getLocaleMessage(props.locale, 'uploadFailed', DEFAULT_MESSAGES.uploadFailed);
316
- handleUploadError(file, errorMessage, map, props);
332
+ handleUploadError(file, errorMessage, map, props, error);
317
333
  return [
318
334
  3,
319
335
  5
@@ -1,3 +1,4 @@
1
+ import type { AttachmentFile } from './types';
1
2
  /**
2
3
  * 将KB转换为可读的文件大小格式
3
4
  * 支持从字节(B)到TB的所有单位,最小单位为B
@@ -40,18 +41,14 @@ export declare const isMediaFile: (file: File) => boolean;
40
41
  /**
41
42
  * 是否为「仅元信息占位」状态:有 status 但无 url/previewUrl,内容未拿到时整行以 FileMetaPlaceholder 风格展示
42
43
  */
43
- export declare const isAttachmentFileLoading: (status?: string | null) => boolean;
44
+ export declare const isAttachmentFileLoading: (status?: AttachmentFile['status'] | null) => boolean;
44
45
  /**
45
46
  * 是否应该展示 FileMetaPlaceholder:
46
47
  * - 有状态
47
48
  * - 非 loading(uploading/pending)
48
49
  * - 且没有可预览 URL
49
50
  */
50
- export declare const isFileMetaPlaceholderState: (file: File & {
51
- status?: string;
52
- url?: string;
53
- previewUrl?: string;
54
- }) => boolean;
51
+ export declare const isFileMetaPlaceholderState: (file: AttachmentFile) => boolean;
55
52
  /**
56
53
  * 获取设备品牌
57
54
  *
@@ -190,7 +190,6 @@ import { ConfigProvider, Image, Modal } from "antd";
190
190
  import classNames from "clsx";
191
191
  import { motion } from "framer-motion";
192
192
  import React, { useContext, useMemo, useState } from "react";
193
- import { I18nContext } from "../../I18n";
194
193
  import { FileMetaPlaceholder } from "../AttachmentButton/AttachmentFileList/AttachmentFileIcon";
195
194
  import { isFileMetaPlaceholderState, isImageFile, isVideoFile } from "../AttachmentButton/utils";
196
195
  import { FileMapViewItem } from "./FileMapViewItem";
@@ -249,7 +248,6 @@ var getMediaPlaceholderStyle = function getMediaPlaceholderStyle(size) {
249
248
  var _props_style;
250
249
  var _props_placement = props.placement, placement = _props_placement === void 0 ? 'left' : _props_placement;
251
250
  var context = useContext(ConfigProvider.ConfigContext);
252
- var locale = useContext(I18nContext).locale;
253
251
  var prefix = context === null || context === void 0 ? void 0 : context.getPrefixCls('agentic-md-editor-file-view-list');
254
252
  var _useStyle = useStyle(prefix), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
255
253
  var _useState = _sliced_to_array(useState(false), 2), showAllFiles = _useState[0], setShowAllFiles = _useState[1];
@@ -351,7 +349,6 @@ var getMediaPlaceholderStyle = function getMediaPlaceholderStyle(size) {
351
349
  width: IMAGE_THUMBNAIL_SIZE,
352
350
  height: IMAGE_THUMBNAIL_SIZE
353
351
  });
354
- var hasAnyFiles = fileList.length > 0;
355
352
  var _obj;
356
353
  return wrapSSR(/*#__PURE__*/ React.createElement("div", {
357
354
  "data-testid": "file-view-list",
@@ -364,10 +361,7 @@ var getMediaPlaceholderStyle = function getMediaPlaceholderStyle(size) {
364
361
  alignItems: placement === 'left' ? 'flex-start' : 'flex-end',
365
362
  width: 'max-content'
366
363
  }
367
- }, hasAnyFiles ? /*#__PURE__*/ React.createElement("div", {
368
- className: classNames("".concat(prefix, "-title"), hashId),
369
- "data-testid": "file-view-title"
370
- }, (locale === null || locale === void 0 ? void 0 : locale['chat.fileMapTitle']) || '结果文件') : null, imgList.length > 0 && /*#__PURE__*/ React.createElement(motion.div, {
364
+ }, imgList.length > 0 && /*#__PURE__*/ React.createElement(motion.div, {
371
365
  variants: {
372
366
  visible: {
373
367
  opacity: 1,
@@ -73,11 +73,10 @@ var genStyle = function genStyle(token) {
73
73
  },
74
74
  '&-vertical': {
75
75
  display: 'flex',
76
- flexDirection: 'row',
77
76
  flexWrap: 'wrap',
78
77
  alignItems: 'flex-start',
79
78
  gap: 4,
80
- padding: 0,
79
+ padding: 2,
81
80
  maxWidth: 'calc(285px * 3 + 4px * 2)',
82
81
  '& > :only-child': {
83
82
  marginTop: 8,