@ant-design/agentic-ui 2.30.11 → 2.30.13
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.
- package/dist/Bubble/MessagesContent/MarkdownPreview.js +3 -2
- package/dist/Bubble/MessagesContent/style.js +3 -1
- package/dist/Bubble/style.js +35 -13
- package/dist/ChatLayout/index.js +9 -1
- package/dist/History/components/HistoryList.d.ts +2 -12
- package/dist/History/components/HistoryList.js +48 -43
- package/dist/History/style.d.ts +4 -0
- package/dist/History/style.js +1 -0
- package/dist/Hooks/useAutoScroll.js +38 -14
- package/dist/Hooks/useLanguage.d.ts +1 -0
- package/dist/I18n/locales.d.ts +1 -0
- package/dist/I18n/locales.js +2 -0
- package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/AgenticUiFileMapBlock.d.ts +4 -0
- package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/AgenticUiFileMapBlock.js +83 -0
- package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils.d.ts +14 -0
- package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils.js +52 -0
- package/dist/MarkdownEditor/editor/elements/index.js +3 -0
- package/dist/MarkdownEditor/editor/parser/parse/parseCode.js +2 -1
- package/dist/MarkdownEditor/editor/parser/parserSlateNodeToMarkdown.js +1 -0
- package/dist/MarkdownEditor/editor/plugins/handlePaste.js +2 -1
- package/dist/MarkdownEditor/types.d.ts +6 -0
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +2 -2
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/style.js +3 -1
- package/dist/MarkdownInputField/AttachmentButton/index.d.ts +12 -0
- package/dist/MarkdownInputField/AttachmentButton/index.js +23 -13
- package/dist/MarkdownInputField/FileMapView/index.d.ts +13 -1
- package/dist/MarkdownInputField/FileMapView/index.js +24 -8
- package/dist/MarkdownInputField/FileUploadManager/index.js +4 -26
- package/dist/MarkdownRenderer/MarkdownRenderer.js +16 -5
- package/dist/MarkdownRenderer/index.d.ts +4 -1
- package/dist/MarkdownRenderer/index.js +3 -0
- package/dist/MarkdownRenderer/renderers/AgenticUiFileMapBlockRenderer.d.ts +8 -0
- package/dist/MarkdownRenderer/renderers/AgenticUiFileMapBlockRenderer.js +121 -0
- package/dist/MarkdownRenderer/renderers/ChartRenderer.js +9 -0
- package/dist/MarkdownRenderer/renderers/index.d.ts +3 -0
- package/dist/MarkdownRenderer/renderers/index.js +3 -0
- package/dist/MarkdownRenderer/types.d.ts +45 -2
- package/dist/Plugins/chart/ChartRender.js +30 -9
- package/dist/Plugins/chart/HistogramChart/index.d.ts +5 -1
- package/dist/Plugins/chart/HistogramChart/index.js +79 -12
- package/dist/Plugins/chart/ScatterChart/index.d.ts +8 -0
- package/dist/Plugins/chart/ScatterChart/index.js +78 -8
- package/dist/Plugins/chart/components/ChartContainer/ChartErrorBoundary.d.ts +2 -0
- package/dist/Plugins/code/components/AceEditor.js +69 -8
- package/dist/Plugins/code/components/CodeRenderer.js +22 -7
- package/dist/Plugins/code/components/CodeToolbar.d.ts +2 -0
- package/dist/Plugins/code/components/CodeToolbar.js +11 -4
- package/dist/Plugins/code/hooks/useToolbarConfig.d.ts +3 -1
- package/dist/Plugins/code/hooks/useToolbarConfig.js +5 -3
- package/dist/Plugins/code/utils/index.d.ts +1 -0
- package/dist/Plugins/code/utils/index.js +1 -0
- package/dist/Plugins/code/utils/localPreview.d.ts +12 -0
- package/dist/Plugins/code/utils/localPreview.js +190 -0
- package/package.json +1 -1
|
@@ -647,4 +647,10 @@ export type MarkdownEditorProps = {
|
|
|
647
647
|
* @returns 自定义渲染节点,或 undefined 时回退到 defaultDom
|
|
648
648
|
*/
|
|
649
649
|
eleRender?: (props: import('../MarkdownRenderer/types').MarkdownRendererEleProps, defaultDom: React.ReactNode) => React.ReactNode;
|
|
650
|
+
/**
|
|
651
|
+
* FileMapView 配置(仅 `renderMode: 'markdown'` 时生效)
|
|
652
|
+
* @description 透传给 agentic-ui-filemap 代码块渲染器,
|
|
653
|
+
* 统一配置图片/视频条目的 onPreview 拦截和 itemRender 自定义回显。
|
|
654
|
+
*/
|
|
655
|
+
fileMapConfig?: import('../MarkdownRenderer/types').FileMapConfig;
|
|
650
656
|
};
|
package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js
CHANGED
|
@@ -105,8 +105,8 @@ export var AttachmentFileListItem = function AttachmentFileListItem(param) {
|
|
|
105
105
|
var file = param.file, prefixCls = param.prefixCls, hashId = param.hashId, onPreview = param.onPreview, onRetry = param.onRetry, onDelete = param.onDelete, className = param.className;
|
|
106
106
|
var locale = useContext(I18nContext).locale;
|
|
107
107
|
var isErrorStatus = file.status === 'error';
|
|
108
|
-
var
|
|
109
|
-
var canRetry = isErrorStatus && !
|
|
108
|
+
var isNonRetryableError = isErrorStatus && (file.errorCode === 'FILE_SIZE_EXCEEDED' || file.errorCode === 'FILE_COUNT_EXCEEDED');
|
|
109
|
+
var canRetry = isErrorStatus && !isNonRetryableError;
|
|
110
110
|
var isDoneStatus = file.status === 'done';
|
|
111
111
|
var canDelete = !isAttachmentFileLoading(file.status);
|
|
112
112
|
var handleFileClick = function handleFileClick() {
|
|
@@ -200,7 +200,9 @@ var genStyle = function genStyle(token) {
|
|
|
200
200
|
alignItems: 'center',
|
|
201
201
|
gap: 4,
|
|
202
202
|
'&-error': {
|
|
203
|
-
color: 'var(--color-red-a10)'
|
|
203
|
+
color: 'var(--color-red-a10)',
|
|
204
|
+
maxWidth: '100%',
|
|
205
|
+
overflow: 'auto'
|
|
204
206
|
},
|
|
205
207
|
'&-item:not(:last-child)': {
|
|
206
208
|
lineHeight: '9px',
|
|
@@ -42,6 +42,12 @@ export type AttachmentButtonProps = {
|
|
|
42
42
|
minFileCount?: number;
|
|
43
43
|
/** 是否允许一次选择多个文件(默认:true) */
|
|
44
44
|
allowMultiple?: boolean;
|
|
45
|
+
/** 文件数量超出 maxFileCount 限制时的回调 */
|
|
46
|
+
onExceedMaxCount?: (info: {
|
|
47
|
+
maxCount: number;
|
|
48
|
+
currentCount: number;
|
|
49
|
+
selectedCount: number;
|
|
50
|
+
}) => void;
|
|
45
51
|
};
|
|
46
52
|
/**
|
|
47
53
|
* 文件上传配置
|
|
@@ -63,6 +69,12 @@ type UploadProps = {
|
|
|
63
69
|
minFileCount?: number;
|
|
64
70
|
/** 国际化文案 */
|
|
65
71
|
locale?: any;
|
|
72
|
+
/** 文件数量超出 maxFileCount 限制时的回调 */
|
|
73
|
+
onExceedMaxCount?: (info: {
|
|
74
|
+
maxCount: number;
|
|
75
|
+
currentCount: number;
|
|
76
|
+
selectedCount: number;
|
|
77
|
+
}) => void;
|
|
66
78
|
};
|
|
67
79
|
/**
|
|
68
80
|
* 上传文件到服务器
|
|
@@ -187,16 +187,6 @@ var prepareFile = function prepareFile(file) {
|
|
|
187
187
|
var getLocaleMessage = function getLocaleMessage(locale, key, defaultMsg) {
|
|
188
188
|
return (locale === null || locale === void 0 ? void 0 : locale[key]) || defaultMsg;
|
|
189
189
|
};
|
|
190
|
-
var validateFileCount = function validateFileCount(newFileCount, existingFileCount, props) {
|
|
191
|
-
var totalFileCount = newFileCount + existingFileCount;
|
|
192
|
-
if (props.maxFileCount && totalFileCount > props.maxFileCount) {
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
if (props.minFileCount && totalFileCount < props.minFileCount) {
|
|
196
|
-
return false;
|
|
197
|
-
}
|
|
198
|
-
return true;
|
|
199
|
-
};
|
|
200
190
|
var validateFileSize = function validateFileSize(file, props) {
|
|
201
191
|
if (!props.maxFileSize || file.size <= props.maxFileSize) return true;
|
|
202
192
|
return false;
|
|
@@ -351,7 +341,7 @@ var processFile = function processFile(file, index, map, props) {
|
|
|
351
341
|
* @param props.locale - 国际化文案
|
|
352
342
|
*/ export var upLoadFileToServer = function upLoadFileToServer(files, props) {
|
|
353
343
|
return _async_to_generator(function() {
|
|
354
|
-
var map, existingFileCount, hideLoading, fileList, i, error;
|
|
344
|
+
var map, existingFileCount, hideLoading, fileList, totalCount, isMaxExceeded, isMinNotMet, _props_onFileMapChange, _props_onExceedMaxCount, maxCount, rawMessage, errorMessage, i, error;
|
|
355
345
|
return _ts_generator(this, function(_state) {
|
|
356
346
|
switch(_state.label){
|
|
357
347
|
case 0:
|
|
@@ -360,9 +350,29 @@ var processFile = function processFile(file, index, map, props) {
|
|
|
360
350
|
hideLoading = function hideLoading() {};
|
|
361
351
|
fileList = Array.from(files);
|
|
362
352
|
fileList.forEach(prepareFile);
|
|
363
|
-
|
|
364
|
-
|
|
353
|
+
totalCount = fileList.length + existingFileCount;
|
|
354
|
+
isMaxExceeded = typeof props.maxFileCount === 'number' && totalCount > props.maxFileCount;
|
|
355
|
+
isMinNotMet = typeof props.minFileCount === 'number' && totalCount < props.minFileCount;
|
|
356
|
+
if (isMaxExceeded || isMinNotMet) {
|
|
365
357
|
hideLoading();
|
|
358
|
+
if (isMaxExceeded) {
|
|
359
|
+
;
|
|
360
|
+
maxCount = props.maxFileCount;
|
|
361
|
+
rawMessage = getLocaleMessage(props.locale, 'markdownInput.maxFileCountExceeded', DEFAULT_MESSAGES.maxFileCountExceeded(maxCount));
|
|
362
|
+
errorMessage = rawMessage.replace(/\$\{maxFileCount\}/g, String(maxCount));
|
|
363
|
+
fileList.forEach(function(file) {
|
|
364
|
+
file.status = 'error';
|
|
365
|
+
file.errorCode = 'FILE_COUNT_EXCEEDED';
|
|
366
|
+
file.errorMessage = errorMessage;
|
|
367
|
+
if (file.uuid) map.set(file.uuid, file);
|
|
368
|
+
});
|
|
369
|
+
(_props_onFileMapChange = props.onFileMapChange) === null || _props_onFileMapChange === void 0 ? void 0 : _props_onFileMapChange.call(props, map);
|
|
370
|
+
(_props_onExceedMaxCount = props.onExceedMaxCount) === null || _props_onExceedMaxCount === void 0 ? void 0 : _props_onExceedMaxCount.call(props, {
|
|
371
|
+
maxCount: maxCount,
|
|
372
|
+
currentCount: existingFileCount,
|
|
373
|
+
selectedCount: fileList.length
|
|
374
|
+
});
|
|
375
|
+
}
|
|
366
376
|
return [
|
|
367
377
|
2
|
|
368
378
|
];
|
|
@@ -5,7 +5,12 @@ export type FileMapViewProps = {
|
|
|
5
5
|
showMoreButton?: boolean;
|
|
6
6
|
/** 文件映射表 */
|
|
7
7
|
fileMap?: Map<string, AttachmentFile>;
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* 预览文件回调。
|
|
10
|
+
* - 对于非图片/视频文件:点击预览按钮时触发,传入时阻止默认的 window.open 行为。
|
|
11
|
+
* - 对于图片文件:点击缩略图时触发,传入时阻止 antd Image 内置灯箱预览。
|
|
12
|
+
* - 对于视频文件:点击缩略图时触发,传入时阻止内置弹窗播放。
|
|
13
|
+
*/
|
|
9
14
|
onPreview?: (file: AttachmentFile) => void;
|
|
10
15
|
/** 下载文件回调 */
|
|
11
16
|
onDownload?: (file: AttachmentFile) => void;
|
|
@@ -22,6 +27,13 @@ export type FileMapViewProps = {
|
|
|
22
27
|
/** 最多展示的非图片文件数量,传入则开启溢出控制并在超出时显示"查看所有文件"按钮,不传则展示所有文件且不显示按钮 */
|
|
23
28
|
maxDisplayCount?: number;
|
|
24
29
|
placement?: 'left' | 'right';
|
|
30
|
+
/**
|
|
31
|
+
* 自定义每个媒体(图片/视频)条目的渲染。
|
|
32
|
+
* 接收文件对象和默认渲染节点,返回自定义节点即可替换默认展示,常用于回显场景。
|
|
33
|
+
* @param file - 当前文件
|
|
34
|
+
* @param defaultDom - 默认渲染的 React 节点
|
|
35
|
+
*/
|
|
36
|
+
itemRender?: (file: AttachmentFile, defaultDom: React.ReactNode) => React.ReactNode;
|
|
25
37
|
};
|
|
26
38
|
/**
|
|
27
39
|
* FileMapView 组件 - 文件映射视图组件
|
|
@@ -368,19 +368,32 @@ import { useStyle } from "./style";
|
|
|
368
368
|
"data-testid": "file-view-image-list",
|
|
369
369
|
className: classNames(prefix, hashId, props.className, "".concat(prefix, "-").concat(placement), (_obj = {}, _define_property(_obj, "".concat(prefix, "-image-list-view"), imgList.length > 1), _define_property(_obj, "".concat(prefix, "-image-list-view-").concat(placement), imgList.length > 1), _obj))
|
|
370
370
|
}, /*#__PURE__*/ React.createElement(Image.PreviewGroup, null, imgList.map(function(file, index) {
|
|
371
|
+
var key = file.uuid || file.name || index;
|
|
371
372
|
if (file.status !== undefined && file.status !== null && !file.url && !file.previewUrl) {
|
|
372
|
-
|
|
373
|
+
var placeholderDom = /*#__PURE__*/ React.createElement(FileMetaPlaceholder, {
|
|
373
374
|
file: file,
|
|
374
|
-
key:
|
|
375
|
+
key: key
|
|
375
376
|
});
|
|
377
|
+
return props.itemRender ? props.itemRender(file, placeholderDom) : placeholderDom;
|
|
376
378
|
}
|
|
377
|
-
|
|
379
|
+
var defaultImageDom = /*#__PURE__*/ React.createElement(Image, {
|
|
378
380
|
rootClassName: classNames("".concat(prefix, "-image"), hashId),
|
|
379
381
|
width: 124,
|
|
380
382
|
height: 124,
|
|
381
383
|
src: file.previewUrl || file.url,
|
|
382
|
-
key:
|
|
384
|
+
key: key,
|
|
385
|
+
preview: props.onPreview ? {
|
|
386
|
+
visible: false,
|
|
387
|
+
onVisibleChange: function onVisibleChange() {
|
|
388
|
+
var _props_onPreview;
|
|
389
|
+
return (_props_onPreview = props.onPreview) === null || _props_onPreview === void 0 ? void 0 : _props_onPreview.call(props, file);
|
|
390
|
+
},
|
|
391
|
+
mask: /*#__PURE__*/ React.createElement("div", {
|
|
392
|
+
className: classNames("".concat(prefix, "-image-mask"), hashId)
|
|
393
|
+
})
|
|
394
|
+
} : undefined
|
|
383
395
|
});
|
|
396
|
+
return props.itemRender ? props.itemRender(file, defaultImageDom) : defaultImageDom;
|
|
384
397
|
}))), videoList.length > 0 && /*#__PURE__*/ React.createElement(motion.div, {
|
|
385
398
|
variants: {
|
|
386
399
|
visible: {
|
|
@@ -406,17 +419,19 @@ import { useStyle } from "./style";
|
|
|
406
419
|
width: 124,
|
|
407
420
|
height: 124
|
|
408
421
|
};
|
|
422
|
+
var key = file.uuid || file.name || index;
|
|
409
423
|
if (file.status !== undefined && file.status !== null && !file.url && !file.previewUrl) {
|
|
410
|
-
|
|
424
|
+
var placeholderDom = /*#__PURE__*/ React.createElement(FileMetaPlaceholder, {
|
|
411
425
|
file: file,
|
|
412
|
-
key:
|
|
426
|
+
key: key
|
|
413
427
|
});
|
|
428
|
+
return props.itemRender ? props.itemRender(file, placeholderDom) : placeholderDom;
|
|
414
429
|
}
|
|
415
|
-
|
|
430
|
+
var defaultVideoDom = /*#__PURE__*/ React.createElement("div", {
|
|
416
431
|
role: "button",
|
|
417
432
|
tabIndex: 0,
|
|
418
433
|
className: classNames("".concat(prefix, "-image"), "".concat(prefix, "-video-thumb"), hashId),
|
|
419
|
-
key:
|
|
434
|
+
key: key,
|
|
420
435
|
onClick: function onClick() {
|
|
421
436
|
return handleVideoClick(file);
|
|
422
437
|
},
|
|
@@ -443,6 +458,7 @@ import { useStyle } from "./style";
|
|
|
443
458
|
className: classNames("".concat(prefix, "-video-play-overlay"), hashId),
|
|
444
459
|
"aria-hidden": true
|
|
445
460
|
}, /*#__PURE__*/ React.createElement(Play, null)));
|
|
461
|
+
return props.itemRender ? props.itemRender(file, defaultVideoDom) : defaultVideoDom;
|
|
446
462
|
})), /*#__PURE__*/ React.createElement(Modal, {
|
|
447
463
|
open: videoModalOpen,
|
|
448
464
|
onCancel: handleVideoModalClose,
|
|
@@ -252,7 +252,7 @@ import { isMobileDevice, isVivoOrOppoDevice, isWeChat } from "../AttachmentButto
|
|
|
252
252
|
* 上传图片
|
|
253
253
|
*/ var uploadImage = useRefFunction(function(forGallery) {
|
|
254
254
|
return _async_to_generator(function() {
|
|
255
|
-
var _ref, isUploading, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file,
|
|
255
|
+
var _ref, isUploading, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file, accept, input;
|
|
256
256
|
return _ts_generator(this, function(_state) {
|
|
257
257
|
// 检查是否有文件正在上传中
|
|
258
258
|
isUploading = false;
|
|
@@ -284,13 +284,6 @@ import { isMobileDevice, isVivoOrOppoDevice, isWeChat } from "../AttachmentButto
|
|
|
284
284
|
2
|
|
285
285
|
];
|
|
286
286
|
}
|
|
287
|
-
// 检查是否已达到最大文件数量限制
|
|
288
|
-
currentFileCount = (fileMap === null || fileMap === void 0 ? void 0 : fileMap.size) || 0;
|
|
289
|
-
if ((attachment === null || attachment === void 0 ? void 0 : attachment.maxFileCount) && currentFileCount >= attachment.maxFileCount) {
|
|
290
|
-
return [
|
|
291
|
-
2
|
|
292
|
-
];
|
|
293
|
-
}
|
|
294
287
|
accept = getAcceptValue(forGallery || false);
|
|
295
288
|
input = document.createElement('input');
|
|
296
289
|
input.id = 'uploadImage' + '_' + Math.random();
|
|
@@ -300,7 +293,7 @@ import { isMobileDevice, isVivoOrOppoDevice, isWeChat } from "../AttachmentButto
|
|
|
300
293
|
input.style.display = 'none';
|
|
301
294
|
input.onchange = function(e) {
|
|
302
295
|
return _async_to_generator(function() {
|
|
303
|
-
var selectedFiles,
|
|
296
|
+
var selectedFiles, error;
|
|
304
297
|
return _ts_generator(this, function(_state) {
|
|
305
298
|
switch(_state.label){
|
|
306
299
|
case 0:
|
|
@@ -324,23 +317,8 @@ import { isMobileDevice, isVivoOrOppoDevice, isWeChat } from "../AttachmentButto
|
|
|
324
317
|
2
|
|
325
318
|
];
|
|
326
319
|
}
|
|
327
|
-
//
|
|
328
|
-
|
|
329
|
-
if (attachment === null || attachment === void 0 ? void 0 : attachment.maxFileCount) {
|
|
330
|
-
// 如果一次选择的文件数量超过最大限制,完全拒绝
|
|
331
|
-
if (selectedFiles.length > attachment.maxFileCount) {
|
|
332
|
-
return [
|
|
333
|
-
2
|
|
334
|
-
];
|
|
335
|
-
}
|
|
336
|
-
// 如果选择的文件数量加上已有文件数量超过限制,完全拒绝
|
|
337
|
-
totalFileCount = selectedFiles.length + currentFileCount;
|
|
338
|
-
if (totalFileCount > attachment.maxFileCount) {
|
|
339
|
-
return [
|
|
340
|
-
2
|
|
341
|
-
];
|
|
342
|
-
}
|
|
343
|
-
}
|
|
320
|
+
// 检查选择的文件数量是否超过限制——超限时交由 upLoadFileToServer 统一处理
|
|
321
|
+
// (upLoadFileToServer 内 validateFileCount 失败时会把文件以 error 状态入 map 并触发 onExceedMaxCount)
|
|
344
322
|
return [
|
|
345
323
|
4,
|
|
346
324
|
upLoadFileToServer(selectedFiles, _object_spread_props(_object_spread({}, attachment), {
|
|
@@ -140,6 +140,7 @@ import { useStyle as useEditorStyle } from "../MarkdownEditor/style";
|
|
|
140
140
|
import { CharacterQueue } from "./CharacterQueue";
|
|
141
141
|
import { AgenticUiTaskBlockRenderer } from "./renderers/AgenticUiTaskBlockRenderer";
|
|
142
142
|
import { AgenticUiToolUseBarBlockRenderer } from "./renderers/AgenticUiToolUseBarBlockRenderer";
|
|
143
|
+
import { AgenticUiFileMapBlockRenderer } from "./renderers/AgenticUiFileMapBlockRenderer";
|
|
143
144
|
import { ChartBlockRenderer } from "./renderers/ChartRenderer";
|
|
144
145
|
import { CodeBlockRenderer } from "./renderers/CodeRenderer";
|
|
145
146
|
import { MermaidBlockRenderer } from "./renderers/MermaidRenderer";
|
|
@@ -186,10 +187,11 @@ var SCHEMA_LANGUAGES = new Set([
|
|
|
186
187
|
/**
|
|
187
188
|
* 默认的代码块路由——根据语言分发到对应渲染器
|
|
188
189
|
*/ var DefaultCodeRouter = function DefaultCodeRouter(props) {
|
|
189
|
-
var language = props.language, pluginComponents = props.pluginComponents, apaasifyRender = props.apaasifyRender, rest = _object_without_properties(props, [
|
|
190
|
+
var language = props.language, pluginComponents = props.pluginComponents, apaasifyRender = props.apaasifyRender, fileMapConfig = props.fileMapConfig, rest = _object_without_properties(props, [
|
|
190
191
|
"language",
|
|
191
192
|
"pluginComponents",
|
|
192
|
-
"apaasifyRender"
|
|
193
|
+
"apaasifyRender",
|
|
194
|
+
"fileMapConfig"
|
|
193
195
|
]);
|
|
194
196
|
if (language === 'mermaid') {
|
|
195
197
|
var MermaidComp = pluginComponents.mermaid || MermaidBlockRenderer;
|
|
@@ -215,6 +217,13 @@ var SCHEMA_LANGUAGES = new Set([
|
|
|
215
217
|
language: language
|
|
216
218
|
}));
|
|
217
219
|
}
|
|
220
|
+
if (language === 'agentic-ui-filemap') {
|
|
221
|
+
var FileMapComp = pluginComponents['agentic-ui-filemap'] || AgenticUiFileMapBlockRenderer;
|
|
222
|
+
return /*#__PURE__*/ React.createElement(FileMapComp, _object_spread_props(_object_spread({}, rest), {
|
|
223
|
+
language: language,
|
|
224
|
+
fileMapConfig: fileMapConfig
|
|
225
|
+
}));
|
|
226
|
+
}
|
|
218
227
|
if (SCHEMA_LANGUAGES.has(language)) {
|
|
219
228
|
var SchemaComp = pluginComponents.schema || SchemaBlockRenderer;
|
|
220
229
|
return /*#__PURE__*/ React.createElement(SchemaComp, _object_spread_props(_object_spread({}, rest), {
|
|
@@ -236,7 +245,7 @@ var SCHEMA_LANGUAGES = new Set([
|
|
|
236
245
|
* - Markdown → hast → React 元素树(hast-util-to-jsx-runtime)
|
|
237
246
|
* - 特殊块(code / mermaid / chart / katex)通过组件映射拦截渲染
|
|
238
247
|
*/ var InternalMarkdownRenderer = /*#__PURE__*/ forwardRef(function(props, ref) {
|
|
239
|
-
var content = props.content, _props_streaming = props.streaming, streaming = _props_streaming === void 0 ? false : _props_streaming, isFinished = props.isFinished, queueOptions = props.queueOptions, plugins = props.plugins, remarkPlugins = props.remarkPlugins, htmlConfig = props.htmlConfig, className = props.className, style = props.style, customPrefixCls = props.prefixCls, linkConfig = props.linkConfig, streamingParagraphAnimation = props.streamingParagraphAnimation, apaasify = props.apaasify, eleRender = props.eleRender;
|
|
248
|
+
var content = props.content, _props_streaming = props.streaming, streaming = _props_streaming === void 0 ? false : _props_streaming, isFinished = props.isFinished, queueOptions = props.queueOptions, plugins = props.plugins, remarkPlugins = props.remarkPlugins, htmlConfig = props.htmlConfig, className = props.className, style = props.style, customPrefixCls = props.prefixCls, linkConfig = props.linkConfig, streamingParagraphAnimation = props.streamingParagraphAnimation, apaasify = props.apaasify, eleRender = props.eleRender, fileMapConfig = props.fileMapConfig;
|
|
240
249
|
var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
|
|
241
250
|
// 复用 MarkdownEditor 的 CSS 前缀和样式,保持渲染一致性
|
|
242
251
|
var prefixCls = getPrefixCls('agentic-md-editor', customPrefixCls);
|
|
@@ -337,7 +346,8 @@ var SCHEMA_LANGUAGES = new Set([
|
|
|
337
346
|
var codeRouter = function codeRouter(codeProps) {
|
|
338
347
|
return /*#__PURE__*/ React.createElement(DefaultCodeRouter, _object_spread_props(_object_spread({}, codeProps), {
|
|
339
348
|
pluginComponents: pluginComponents,
|
|
340
|
-
apaasifyRender: apaasifyRender
|
|
349
|
+
apaasifyRender: apaasifyRender,
|
|
350
|
+
fileMapConfig: fileMapConfig
|
|
341
351
|
}));
|
|
342
352
|
};
|
|
343
353
|
codeRouter.displayName = 'CodeRouter';
|
|
@@ -346,7 +356,8 @@ var SCHEMA_LANGUAGES = new Set([
|
|
|
346
356
|
}, pluginComponents);
|
|
347
357
|
}, [
|
|
348
358
|
pluginComponents,
|
|
349
|
-
apaasifyRender
|
|
359
|
+
apaasifyRender,
|
|
360
|
+
fileMapConfig
|
|
350
361
|
]);
|
|
351
362
|
// 流式缓存:将不完整的 Markdown token 暂缓,避免 parser 错误解析
|
|
352
363
|
var safeContent = useStreaming(displayedContent, streaming);
|
|
@@ -2,11 +2,14 @@ export { default as AnimationText } from './AnimationText';
|
|
|
2
2
|
export type { AnimationConfig, AnimationTextProps } from './AnimationText';
|
|
3
3
|
export { CharacterQueue } from './CharacterQueue';
|
|
4
4
|
export { default as MarkdownRenderer } from './MarkdownRenderer';
|
|
5
|
+
export { AgenticUiFileMapBlockRenderer } from './renderers/AgenticUiFileMapBlockRenderer';
|
|
6
|
+
export { AgenticUiTaskBlockRenderer } from './renderers/AgenticUiTaskBlockRenderer';
|
|
7
|
+
export { AgenticUiToolUseBarBlockRenderer } from './renderers/AgenticUiToolUseBarBlockRenderer';
|
|
5
8
|
export { ChartBlockRenderer } from './renderers/ChartRenderer';
|
|
6
9
|
export { CodeBlockRenderer } from './renderers/CodeRenderer';
|
|
7
10
|
export { MermaidBlockRenderer } from './renderers/MermaidRenderer';
|
|
8
11
|
export { SchemaBlockRenderer } from './renderers/SchemaRenderer';
|
|
9
|
-
export type { CharacterQueueOptions, MarkdownRendererEleProps, MarkdownRendererProps, MarkdownRendererRef, RenderMode, RendererBlockProps, } from './types';
|
|
12
|
+
export type { CharacterQueueOptions, FileMapConfig, MarkdownRendererEleProps, MarkdownRendererProps, MarkdownRendererRef, RenderMode, RendererBlockProps, } from './types';
|
|
10
13
|
export type { UseMarkdownToReactOptions } from './markdownReactShared';
|
|
11
14
|
export { markdownToReactSync, useMarkdownToReact } from './useMarkdownToReact';
|
|
12
15
|
export { useStreamingMarkdownReact } from './streaming/useStreamingMarkdownReact';
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export { default as AnimationText } from "./AnimationText";
|
|
2
2
|
export { CharacterQueue } from "./CharacterQueue";
|
|
3
3
|
export { default as MarkdownRenderer } from "./MarkdownRenderer";
|
|
4
|
+
export { AgenticUiFileMapBlockRenderer } from "./renderers/AgenticUiFileMapBlockRenderer";
|
|
5
|
+
export { AgenticUiTaskBlockRenderer } from "./renderers/AgenticUiTaskBlockRenderer";
|
|
6
|
+
export { AgenticUiToolUseBarBlockRenderer } from "./renderers/AgenticUiToolUseBarBlockRenderer";
|
|
4
7
|
export { ChartBlockRenderer } from "./renderers/ChartRenderer";
|
|
5
8
|
export { CodeBlockRenderer } from "./renderers/CodeRenderer";
|
|
6
9
|
export { MermaidBlockRenderer } from "./renderers/MermaidRenderer";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FileMapConfig, RendererBlockProps } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* ```agentic-ui-filemap``` 代码块 → FileMapView
|
|
5
|
+
*/
|
|
6
|
+
export declare const AgenticUiFileMapBlockRenderer: React.FC<RendererBlockProps & {
|
|
7
|
+
fileMapConfig?: FileMapConfig;
|
|
8
|
+
}>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
function _object_without_properties(source, excluded) {
|
|
2
|
+
if (source == null) return {};
|
|
3
|
+
var target = {}, sourceKeys, key, i;
|
|
4
|
+
if (typeof Reflect !== "undefined" && Reflect.ownKeys) {
|
|
5
|
+
sourceKeys = Reflect.ownKeys(source);
|
|
6
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
7
|
+
key = sourceKeys[i];
|
|
8
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
9
|
+
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
10
|
+
target[key] = source[key];
|
|
11
|
+
}
|
|
12
|
+
return target;
|
|
13
|
+
}
|
|
14
|
+
target = _object_without_properties_loose(source, excluded);
|
|
15
|
+
if (Object.getOwnPropertySymbols) {
|
|
16
|
+
sourceKeys = Object.getOwnPropertySymbols(source);
|
|
17
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
18
|
+
key = sourceKeys[i];
|
|
19
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
20
|
+
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
21
|
+
target[key] = source[key];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return target;
|
|
25
|
+
}
|
|
26
|
+
function _object_without_properties_loose(source, excluded) {
|
|
27
|
+
if (source == null) return {};
|
|
28
|
+
var target = {}, sourceKeys = Object.getOwnPropertyNames(source), key, i;
|
|
29
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
30
|
+
key = sourceKeys[i];
|
|
31
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
32
|
+
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
33
|
+
target[key] = source[key];
|
|
34
|
+
}
|
|
35
|
+
return target;
|
|
36
|
+
}
|
|
37
|
+
import json5 from "json5";
|
|
38
|
+
import React, { useMemo } from "react";
|
|
39
|
+
import { normalizeFileMapPropsFromJson } from "../../MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils";
|
|
40
|
+
import partialParse from "../../MarkdownEditor/editor/parser/json-parse";
|
|
41
|
+
import { FileMapView } from "../../MarkdownInputField/FileMapView";
|
|
42
|
+
var extractTextContent = function extractTextContent1(children) {
|
|
43
|
+
var _children_props;
|
|
44
|
+
if (typeof children === 'string') return children;
|
|
45
|
+
if (typeof children === 'number') return String(children);
|
|
46
|
+
if (Array.isArray(children)) return children.map(extractTextContent).join('');
|
|
47
|
+
if (/*#__PURE__*/ React.isValidElement(children) && ((_children_props = children.props) === null || _children_props === void 0 ? void 0 : _children_props.children)) {
|
|
48
|
+
return extractTextContent(children.props.children);
|
|
49
|
+
}
|
|
50
|
+
return '';
|
|
51
|
+
};
|
|
52
|
+
var parseJsonBody = function parseJsonBody(code) {
|
|
53
|
+
try {
|
|
54
|
+
return json5.parse(code || '{}');
|
|
55
|
+
} catch (unused) {
|
|
56
|
+
try {
|
|
57
|
+
return partialParse(code || '{}');
|
|
58
|
+
} catch (unused) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* ```agentic-ui-filemap``` 代码块 → FileMapView
|
|
65
|
+
*/ export var AgenticUiFileMapBlockRenderer = function AgenticUiFileMapBlockRenderer(props) {
|
|
66
|
+
var fileMapConfig = props.fileMapConfig, rest = _object_without_properties(props, [
|
|
67
|
+
"fileMapConfig"
|
|
68
|
+
]);
|
|
69
|
+
var code = useMemo(function() {
|
|
70
|
+
return extractTextContent(rest.children);
|
|
71
|
+
}, [
|
|
72
|
+
rest.children
|
|
73
|
+
]);
|
|
74
|
+
var parsed = useMemo(function() {
|
|
75
|
+
return parseJsonBody(code);
|
|
76
|
+
}, [
|
|
77
|
+
code
|
|
78
|
+
]);
|
|
79
|
+
var _useMemo = useMemo(function() {
|
|
80
|
+
return normalizeFileMapPropsFromJson(parsed, fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.normalizeFile);
|
|
81
|
+
}, [
|
|
82
|
+
parsed,
|
|
83
|
+
fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.normalizeFile
|
|
84
|
+
]), fileList = _useMemo.fileList, className = _useMemo.className;
|
|
85
|
+
var fileMap = useMemo(function() {
|
|
86
|
+
return new Map(fileList.map(function(f) {
|
|
87
|
+
return [
|
|
88
|
+
f.uuid || f.name,
|
|
89
|
+
f
|
|
90
|
+
];
|
|
91
|
+
}));
|
|
92
|
+
}, [
|
|
93
|
+
fileList
|
|
94
|
+
]);
|
|
95
|
+
if (parsed === null) {
|
|
96
|
+
return /*#__PURE__*/ React.createElement("pre", {
|
|
97
|
+
"data-testid": "agentic-ui-filemap-fallback",
|
|
98
|
+
style: {
|
|
99
|
+
background: 'rgb(242, 241, 241)',
|
|
100
|
+
padding: '1em',
|
|
101
|
+
borderRadius: '0.5em',
|
|
102
|
+
margin: '0.75em 0',
|
|
103
|
+
fontSize: '0.8em',
|
|
104
|
+
whiteSpace: 'pre-wrap',
|
|
105
|
+
wordBreak: 'break-all'
|
|
106
|
+
}
|
|
107
|
+
}, /*#__PURE__*/ React.createElement("code", null, code));
|
|
108
|
+
}
|
|
109
|
+
return /*#__PURE__*/ React.createElement("div", {
|
|
110
|
+
"data-testid": "agentic-ui-filemap-block",
|
|
111
|
+
style: {
|
|
112
|
+
margin: '0.75em 0'
|
|
113
|
+
}
|
|
114
|
+
}, /*#__PURE__*/ React.createElement(FileMapView, {
|
|
115
|
+
fileMap: fileMap,
|
|
116
|
+
className: className,
|
|
117
|
+
onPreview: fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.onPreview,
|
|
118
|
+
itemRender: fileMapConfig === null || fileMapConfig === void 0 ? void 0 : fileMapConfig.itemRender
|
|
119
|
+
}));
|
|
120
|
+
};
|
|
121
|
+
AgenticUiFileMapBlockRenderer.displayName = 'AgenticUiFileMapBlockRenderer';
|
|
@@ -158,6 +158,7 @@ var extractTextContent = function extractTextContent1(children) {
|
|
|
158
158
|
* 支持两种格式:
|
|
159
159
|
* 1. 完整格式:{ config: [...], dataSource: [...], columns: [...] }
|
|
160
160
|
* 2. 简单格式:{ chartType, x, y, data: [...] }
|
|
161
|
+
* 3. algTypes 格式:{ type: "histogram", value: { data: [...], dataMetaMap: {...} } }
|
|
161
162
|
*/ var parseChartData = function parseChartData(code) {
|
|
162
163
|
try {
|
|
163
164
|
var parsed = JSON.parse(code.trim());
|
|
@@ -167,6 +168,14 @@ var extractTextContent = function extractTextContent1(children) {
|
|
|
167
168
|
config: parsed
|
|
168
169
|
};
|
|
169
170
|
}
|
|
171
|
+
// Handle { type: "histogram", value: { data: [...], dataMetaMap: {...} } } format
|
|
172
|
+
if (typeof parsed.type === 'string' && parsed.value && Array.isArray(parsed.value.data)) {
|
|
173
|
+
return {
|
|
174
|
+
chartType: parsed.type,
|
|
175
|
+
data: parsed.value.data,
|
|
176
|
+
dataMetaMap: parsed.value.dataMetaMap
|
|
177
|
+
};
|
|
178
|
+
}
|
|
170
179
|
return parsed;
|
|
171
180
|
} catch (unused) {
|
|
172
181
|
return null;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export { AgenticUiFileMapBlockRenderer } from './AgenticUiFileMapBlockRenderer';
|
|
2
|
+
export { AgenticUiTaskBlockRenderer } from './AgenticUiTaskBlockRenderer';
|
|
3
|
+
export { AgenticUiToolUseBarBlockRenderer } from './AgenticUiToolUseBarBlockRenderer';
|
|
1
4
|
export { ChartBlockRenderer } from './ChartRenderer';
|
|
2
5
|
export { CodeBlockRenderer } from './CodeRenderer';
|
|
3
6
|
export { MermaidBlockRenderer } from './MermaidRenderer';
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export { AgenticUiFileMapBlockRenderer } from "./AgenticUiFileMapBlockRenderer";
|
|
2
|
+
export { AgenticUiTaskBlockRenderer } from "./AgenticUiTaskBlockRenderer";
|
|
3
|
+
export { AgenticUiToolUseBarBlockRenderer } from "./AgenticUiToolUseBarBlockRenderer";
|
|
1
4
|
export { ChartBlockRenderer } from "./ChartRenderer";
|
|
2
5
|
export { CodeBlockRenderer } from "./CodeRenderer";
|
|
3
6
|
export { MermaidBlockRenderer } from "./MermaidRenderer";
|
|
@@ -1,10 +1,48 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import type { MarkdownRemarkPlugin, MarkdownToHtmlConfig } from '../MarkdownEditor/editor/utils/markdownToHtml';
|
|
3
3
|
import type { MarkdownEditorPlugin } from '../MarkdownEditor/plugin';
|
|
4
|
+
import type { AttachmentFile } from '../MarkdownInputField/AttachmentButton/types';
|
|
5
|
+
import type { FileMapViewProps } from '../MarkdownInputField/FileMapView';
|
|
4
6
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
+
* FileMapView 相关配置,透传给 agentic-ui-filemap 代码块渲染器,
|
|
8
|
+
* 方便在 markdownRenderConfig 中统一配置图片回显行为。
|
|
7
9
|
*/
|
|
10
|
+
export interface FileMapConfig {
|
|
11
|
+
/**
|
|
12
|
+
* 预览文件回调,透传给 FileMapView.onPreview。
|
|
13
|
+
* 对图片:点击缩略图时触发,传入则阻止 antd Image 内置灯箱;
|
|
14
|
+
* 对视频:传入则阻止内置弹窗;对普通文件:传入则阻止默认 window.open。
|
|
15
|
+
*/
|
|
16
|
+
onPreview?: (file: AttachmentFile) => void;
|
|
17
|
+
/**
|
|
18
|
+
* 自定义每个媒体条目(图片/视频)的渲染,透传给 FileMapView.itemRender,
|
|
19
|
+
* 常用于回显场景。
|
|
20
|
+
*/
|
|
21
|
+
itemRender?: FileMapViewProps['itemRender'];
|
|
22
|
+
/**
|
|
23
|
+
* 自定义文件数据规范化函数,用于将 agentic-ui-filemap 代码块中的原始 JSON 条目
|
|
24
|
+
* 转换为 AttachmentFile 对象。
|
|
25
|
+
*
|
|
26
|
+
* 适用于服务端返回的字段名与 AttachmentFile 不一致(如 fileUrl → url、
|
|
27
|
+
* fileId → uuid)或需要在数据层补充额外字段的场景。
|
|
28
|
+
*
|
|
29
|
+
* @param raw - 代码块 JSON 中的原始文件对象(未经处理)
|
|
30
|
+
* @param defaultFile - 由内置逻辑生成的默认 AttachmentFile,可在此基础上做局部覆盖
|
|
31
|
+
* @returns 转换后的 AttachmentFile;返回 null 时该条目将被过滤掉
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* fileMapConfig={{
|
|
36
|
+
* normalizeFile: (raw, defaultFile) => ({
|
|
37
|
+
* ...defaultFile,
|
|
38
|
+
* url: raw.fileUrl as string,
|
|
39
|
+
* uuid: raw.fileId as string,
|
|
40
|
+
* }),
|
|
41
|
+
* }}
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
normalizeFile?: (raw: Record<string, unknown>, defaultFile: AttachmentFile) => AttachmentFile | null;
|
|
45
|
+
}
|
|
8
46
|
export interface MarkdownRendererEleProps {
|
|
9
47
|
/** HTML tag name, e.g. 'p', 'h1', 'blockquote', 'pre' */
|
|
10
48
|
tagName: string;
|
|
@@ -92,6 +130,11 @@ export interface MarkdownRendererProps {
|
|
|
92
130
|
/** 自定义渲染函数,接收解析后的 JSON value,返回 React 节点 */
|
|
93
131
|
render?: (value: any) => React.ReactNode;
|
|
94
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* FileMapView 配置,透传给 agentic-ui-filemap 代码块渲染器。
|
|
135
|
+
* 可在 markdownRenderConfig 中统一配置图片 onPreview 和 itemRender。
|
|
136
|
+
*/
|
|
137
|
+
fileMapConfig?: FileMapConfig;
|
|
95
138
|
/**
|
|
96
139
|
* 自定义元素渲染函数(markdown 渲染模式)
|
|
97
140
|
* 与 Slate 模式的 eleItemRender 对应,允许拦截并替换任意块级/行内元素的渲染结果。
|