@ant-design/agentic-ui 2.30.0 → 2.30.1

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 (63) hide show
  1. package/dist/Bubble/List/index.d.ts +4 -0
  2. package/dist/Bubble/List/index.js +8 -5
  3. package/dist/Bubble/MessagesContent/EXCEPTION.js +11 -2
  4. package/dist/Bubble/MessagesContent/MarkdownPreview.js +13 -7
  5. package/dist/Bubble/MessagesContent/index.js +39 -10
  6. package/dist/Bubble/MessagesContent/style.js +55 -22
  7. package/dist/Bubble/type.d.ts +4 -0
  8. package/dist/I18n/locales.js +2 -2
  9. package/dist/MarkdownEditor/BaseMarkdownEditor.js +37 -5
  10. package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/AgenticUiTaskBlock.d.ts +4 -0
  11. package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/AgenticUiTaskBlock.js +74 -0
  12. package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/AgenticUiToolUseBarBlock.d.ts +4 -0
  13. package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/AgenticUiToolUseBarBlock.js +114 -0
  14. package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils.d.ts +20 -0
  15. package/dist/MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils.js +169 -0
  16. package/dist/MarkdownEditor/editor/elements/Table/EditableTable.d.ts +11 -0
  17. package/dist/MarkdownEditor/editor/elements/Table/EditableTable.js +207 -0
  18. package/dist/MarkdownEditor/editor/elements/Table/Table.js +10 -276
  19. package/dist/MarkdownEditor/editor/elements/Table/TableCellIndex/index.js +7 -227
  20. package/dist/MarkdownEditor/editor/elements/Table/TableCellIndexSpacer/index.js +20 -229
  21. package/dist/MarkdownEditor/editor/elements/Table/commands/tableCommands.d.ts +9 -0
  22. package/dist/MarkdownEditor/editor/elements/Table/commands/tableCommands.js +242 -0
  23. package/dist/MarkdownEditor/editor/elements/Table/utils/editableTableWidth.d.ts +20 -0
  24. package/dist/MarkdownEditor/editor/elements/Table/utils/editableTableWidth.js +60 -0
  25. package/dist/MarkdownEditor/editor/elements/Table/utils/useEditableTableColWidths.d.ts +6 -0
  26. package/dist/MarkdownEditor/editor/elements/Table/utils/useEditableTableColWidths.js +20 -0
  27. package/dist/MarkdownEditor/editor/elements/Table/utils/useEditableTableContentWidth.d.ts +10 -0
  28. package/dist/MarkdownEditor/editor/elements/Table/utils/useEditableTableContentWidth.js +103 -0
  29. package/dist/MarkdownEditor/editor/elements/index.js +7 -0
  30. package/dist/MarkdownEditor/editor/parser/parse/parseCode.js +33 -2
  31. package/dist/MarkdownEditor/editor/parser/parserSlateNodeToMarkdown.js +3 -0
  32. package/dist/MarkdownEditor/editor/plugins/handlePaste.js +4 -1
  33. package/dist/MarkdownEditor/style.js +109 -7
  34. package/dist/MarkdownEditor/types.d.ts +5 -0
  35. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileIcon.js +2 -2
  36. package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +11 -8
  37. package/dist/MarkdownInputField/AttachmentButton/index.js +7 -2
  38. package/dist/MarkdownInputField/AttachmentButton/types.d.ts +5 -1
  39. package/dist/MarkdownInputField/AttachmentButton/utils.d.ts +7 -0
  40. package/dist/MarkdownInputField/AttachmentButton/utils.js +9 -1
  41. package/dist/MarkdownInputField/FileMapView/FileMapViewItem.js +10 -5
  42. package/dist/MarkdownInputField/FileUploadManager/index.d.ts +9 -0
  43. package/dist/MarkdownInputField/FileUploadManager/index.js +20 -4
  44. package/dist/MarkdownInputField/MarkdownInputField.js +5 -3
  45. package/dist/MarkdownInputField/SendActions/index.d.ts +9 -0
  46. package/dist/MarkdownInputField/SendActions/index.js +3 -2
  47. package/dist/MarkdownInputField/utils/renderHelpers.d.ts +8 -1
  48. package/dist/MarkdownInputField/utils/renderHelpers.js +5 -1
  49. package/dist/MarkdownRenderer/AnimationText.d.ts +4 -7
  50. package/dist/MarkdownRenderer/AnimationText.js +117 -15
  51. package/dist/MarkdownRenderer/MarkdownRenderer.js +15 -1
  52. package/dist/MarkdownRenderer/index.d.ts +2 -2
  53. package/dist/MarkdownRenderer/index.js +1 -1
  54. package/dist/MarkdownRenderer/renderers/AgenticUiTaskBlockRenderer.d.ts +6 -0
  55. package/dist/MarkdownRenderer/renderers/AgenticUiTaskBlockRenderer.js +66 -0
  56. package/dist/MarkdownRenderer/renderers/AgenticUiToolUseBarBlockRenderer.d.ts +6 -0
  57. package/dist/MarkdownRenderer/renderers/AgenticUiToolUseBarBlockRenderer.js +134 -0
  58. package/dist/MarkdownRenderer/style.js +7 -6
  59. package/dist/MarkdownRenderer/useMarkdownToReact.js +5 -4
  60. package/dist/MarkdownRenderer/useStreaming.js +8 -1
  61. package/dist/Plugins/chart/ChartRender.js +1 -0
  62. package/dist/Plugins/chart/index.js +3 -1
  63. package/package.json +2 -1
@@ -191,10 +191,24 @@ import { isMobileDevice, isVivoOrOppoDevice, isWeChat } from "../AttachmentButto
191
191
  */ export var useFileUploadManager = function useFileUploadManager(param) {
192
192
  var attachment = param.attachment, fileMap = param.fileMap, onFileMapChange = param.onFileMapChange;
193
193
  var locale = useContext(I18nContext).locale;
194
- // 判断是否所有文件上传完成
195
- var fileUploadDone = (fileMap === null || fileMap === void 0 ? void 0 : fileMap.size) ? Array.from((fileMap === null || fileMap === void 0 ? void 0 : fileMap.values()) || []).every(function(file) {
196
- return file.status === 'done';
197
- }) : true;
194
+ var fileList = Array.from((fileMap === null || fileMap === void 0 ? void 0 : fileMap.values()) || []);
195
+ var uploadingCount = fileList.filter(function(file) {
196
+ return file.status === 'uploading';
197
+ }).length;
198
+ var errorCount = fileList.filter(function(file) {
199
+ return file.status === 'error';
200
+ }).length;
201
+ var totalCount = fileList.length;
202
+ var fileUploadSummary = {
203
+ totalCount: totalCount,
204
+ uploadingCount: uploadingCount,
205
+ errorCount: errorCount,
206
+ // 兜底把未知状态也按完成态处理,避免统计缺口
207
+ doneCount: Math.max(0, totalCount - uploadingCount - errorCount)
208
+ };
209
+ var fileUploadStatus = fileUploadSummary.errorCount > 0 ? 'error' : fileUploadSummary.uploadingCount > 0 ? 'uploading' : 'done';
210
+ // 向后兼容:无文件时视为已完成
211
+ var fileUploadDone = fileUploadSummary.totalCount > 0 ? fileUploadStatus === 'done' : true;
198
212
  // 默认支持的文件格式
199
213
  var supportedFormat = (attachment === null || attachment === void 0 ? void 0 : attachment.supportedFormat) || SupportedFileFormats.image;
200
214
  /**
@@ -507,6 +521,8 @@ import { isMobileDevice, isVivoOrOppoDevice, isWeChat } from "../AttachmentButto
507
521
  return {
508
522
  fileMap: fileMap,
509
523
  fileUploadDone: fileUploadDone,
524
+ fileUploadStatus: fileUploadStatus,
525
+ fileUploadSummary: fileUploadSummary,
510
526
  supportedFormat: supportedFormat,
511
527
  uploadImage: uploadImage,
512
528
  updateAttachmentFiles: updateAttachmentFiles,
@@ -258,7 +258,7 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
258
258
  attachment: attachment,
259
259
  fileMap: fileMap,
260
260
  onFileMapChange: setFileMap
261
- }), fileUploadDone = _useFileUploadManager.fileUploadDone, supportedFormat = _useFileUploadManager.supportedFormat, uploadImage = _useFileUploadManager.uploadImage, updateAttachmentFiles = _useFileUploadManager.updateAttachmentFiles, handleFileRemoval = _useFileUploadManager.handleFileRemoval, handleFileRetry = _useFileUploadManager.handleFileRetry;
261
+ }), fileUploadDone = _useFileUploadManager.fileUploadDone, fileUploadStatus = _useFileUploadManager.fileUploadStatus, fileUploadSummary = _useFileUploadManager.fileUploadSummary, supportedFormat = _useFileUploadManager.supportedFormat, uploadImage = _useFileUploadManager.uploadImage, updateAttachmentFiles = _useFileUploadManager.updateAttachmentFiles, handleFileRemoval = _useFileUploadManager.handleFileRemoval, handleFileRetry = _useFileUploadManager.handleFileRetry;
262
262
  // 语音输入管理
263
263
  var _useVoiceInputManager = useVoiceInputManager({
264
264
  voiceRecognizer: props.voiceRecognizer,
@@ -322,6 +322,8 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
322
322
  setFileMap: setFileMap,
323
323
  supportedFormat: supportedFormat,
324
324
  fileUploadDone: fileUploadDone,
325
+ fileUploadStatus: fileUploadStatus,
326
+ fileUploadSummary: fileUploadSummary,
325
327
  recording: recording,
326
328
  isLoading: isLoading,
327
329
  collapseSendActions: collapseSendActions,
@@ -473,7 +475,7 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
473
475
  isHover: isHover,
474
476
  isLoading: isLoading,
475
477
  disabled: props.disabled,
476
- fileUploadStatus: fileUploadDone ? 'done' : 'uploading',
478
+ fileUploadStatus: fileUploadStatus,
477
479
  refinePrompt: props.refinePrompt,
478
480
  editorRef: markdownEditorRef,
479
481
  onValueChange: function onValueChange(text) {
@@ -507,7 +509,7 @@ var MarkdownInputFieldComponent = function MarkdownInputFieldComponent(_0) {
507
509
  }, props), {
508
510
  isHover: isHover,
509
511
  isLoading: isLoading,
510
- fileUploadStatus: fileUploadDone ? 'done' : 'uploading'
512
+ fileUploadStatus: fileUploadStatus
511
513
  }))), sendActionsNode) : sendActionsNode))));
512
514
  };
513
515
  MarkdownInputFieldComponent.displayName = 'MarkdownInputField';
@@ -25,6 +25,15 @@ export interface SendActionsProps {
25
25
  isLoading?: boolean;
26
26
  /** 文件上传是否完成 */
27
27
  fileUploadDone?: boolean;
28
+ /** 文件上传状态 */
29
+ fileUploadStatus?: 'uploading' | 'done' | 'error';
30
+ /** 文件上传状态统计 */
31
+ fileUploadSummary?: {
32
+ totalCount: number;
33
+ doneCount: number;
34
+ uploadingCount: number;
35
+ errorCount: number;
36
+ };
28
37
  /** 是否正在录音 */
29
38
  recording?: boolean;
30
39
  /** 是否折叠操作按钮 */
@@ -66,7 +66,7 @@ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
66
66
  *
67
67
  * @description 封装发送操作相关的按钮,包括附件上传、语音输入、发送按钮等
68
68
  */ export var SendActions = function SendActions(param) {
69
- var attachment = param.attachment, voiceRecognizer = param.voiceRecognizer, value = param.value, disabled = param.disabled, typing = param.typing, isLoading = param.isLoading, _param_fileUploadDone = param.fileUploadDone, fileUploadDone = _param_fileUploadDone === void 0 ? true : _param_fileUploadDone, _param_recording = param.recording, recording = _param_recording === void 0 ? false : _param_recording, _param_collapseSendActions = param.collapseSendActions, collapseSendActions = _param_collapseSendActions === void 0 ? false : _param_collapseSendActions, _param_allowEmptySubmit = param.allowEmptySubmit, allowEmptySubmit = _param_allowEmptySubmit === void 0 ? false : _param_allowEmptySubmit, uploadImage = param.uploadImage, onStartRecording = param.onStartRecording, onStopRecording = param.onStopRecording, onSend = param.onSend, onStop = param.onStop, actionsRender = param.actionsRender, _param_prefixCls = param.prefixCls, prefixCls = _param_prefixCls === void 0 ? 'ant-agentic-md-input-field' : _param_prefixCls, _param_hashId = param.hashId, hashId = _param_hashId === void 0 ? '' : _param_hashId, _param_hasTools = param.hasTools, hasTools = _param_hasTools === void 0 ? false : _param_hasTools, onResize = param.onResize, sendButtonProps = param.sendButtonProps, triggerSendKey = param.triggerSendKey;
69
+ var attachment = param.attachment, voiceRecognizer = param.voiceRecognizer, value = param.value, disabled = param.disabled, typing = param.typing, isLoading = param.isLoading, _param_fileUploadDone = param.fileUploadDone, fileUploadDone = _param_fileUploadDone === void 0 ? true : _param_fileUploadDone, _param_fileUploadStatus = param.fileUploadStatus, fileUploadStatus = _param_fileUploadStatus === void 0 ? fileUploadDone ? 'done' : 'uploading' : _param_fileUploadStatus, fileUploadSummary = param.fileUploadSummary, _param_recording = param.recording, recording = _param_recording === void 0 ? false : _param_recording, _param_collapseSendActions = param.collapseSendActions, collapseSendActions = _param_collapseSendActions === void 0 ? false : _param_collapseSendActions, _param_allowEmptySubmit = param.allowEmptySubmit, allowEmptySubmit = _param_allowEmptySubmit === void 0 ? false : _param_allowEmptySubmit, uploadImage = param.uploadImage, onStartRecording = param.onStartRecording, onStopRecording = param.onStopRecording, onSend = param.onSend, onStop = param.onStop, actionsRender = param.actionsRender, _param_prefixCls = param.prefixCls, prefixCls = _param_prefixCls === void 0 ? 'ant-agentic-md-input-field' : _param_prefixCls, _param_hashId = param.hashId, hashId = _param_hashId === void 0 ? '' : _param_hashId, _param_hasTools = param.hasTools, hasTools = _param_hasTools === void 0 ? false : _param_hasTools, onResize = param.onResize, sendButtonProps = param.sendButtonProps, triggerSendKey = param.triggerSendKey;
70
70
  var fileMap = attachment === null || attachment === void 0 ? void 0 : attachment.fileMap;
71
71
  var defaultActionsLen = [
72
72
  (attachment === null || attachment === void 0 ? void 0 : attachment.enable) ? '()' : null,
@@ -155,7 +155,8 @@ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
155
155
  onStopRecording: onStopRecording,
156
156
  onSend: onSend,
157
157
  onStop: onStop,
158
- fileUploadStatus: fileUploadDone ? 'done' : 'uploading'
158
+ fileUploadStatus: fileUploadStatus,
159
+ fileUploadSummary: fileUploadSummary
159
160
  }, defaultActions) : defaultActions;
160
161
  return /*#__PURE__*/ React.createElement(RcResizeObserver, {
161
162
  onResize: function onResize1(e) {
@@ -29,6 +29,13 @@ interface UseSendActionsNodeParams {
29
29
  setFileMap?: (fileMap?: Map<string, AttachmentFile>) => void;
30
30
  supportedFormat: AttachmentButtonProps['supportedFormat'];
31
31
  fileUploadDone: boolean;
32
+ fileUploadStatus: 'uploading' | 'done' | 'error';
33
+ fileUploadSummary: {
34
+ totalCount: number;
35
+ doneCount: number;
36
+ uploadingCount: number;
37
+ errorCount: number;
38
+ };
32
39
  recording: boolean;
33
40
  isLoading: boolean;
34
41
  collapseSendActions: boolean;
@@ -45,5 +52,5 @@ interface UseSendActionsNodeParams {
45
52
  /**
46
53
  * SendActions 节点渲染 Hook
47
54
  */
48
- export declare const useSendActionsNode: ({ props: sendProps, fileMap, setFileMap, supportedFormat, fileUploadDone, recording, isLoading, collapseSendActions, uploadImage, startRecording, stopRecording, sendMessage, setIsLoading, onStop, setRightPadding, baseCls, hashId, }: UseSendActionsNodeParams) => React.ReactElement;
55
+ export declare const useSendActionsNode: ({ props: sendProps, fileMap, setFileMap, supportedFormat, fileUploadDone, fileUploadStatus, fileUploadSummary, recording, isLoading, collapseSendActions, uploadImage, startRecording, stopRecording, sendMessage, setIsLoading, onStop, setRightPadding, baseCls, hashId, }: UseSendActionsNodeParams) => React.ReactElement;
49
56
  export {};
@@ -99,7 +99,7 @@ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
99
99
  /**
100
100
  * SendActions 节点渲染 Hook
101
101
  */ export var useSendActionsNode = function useSendActionsNode(param) {
102
- var sendProps = param.props, fileMap = param.fileMap, setFileMap = param.setFileMap, supportedFormat = param.supportedFormat, fileUploadDone = param.fileUploadDone, recording = param.recording, isLoading = param.isLoading, collapseSendActions = param.collapseSendActions, uploadImage = param.uploadImage, startRecording = param.startRecording, stopRecording = param.stopRecording, sendMessage = param.sendMessage, setIsLoading = param.setIsLoading, onStop = param.onStop, setRightPadding = param.setRightPadding, baseCls = param.baseCls, hashId = param.hashId;
102
+ var sendProps = param.props, fileMap = param.fileMap, setFileMap = param.setFileMap, supportedFormat = param.supportedFormat, fileUploadDone = param.fileUploadDone, fileUploadStatus = param.fileUploadStatus, fileUploadSummary = param.fileUploadSummary, recording = param.recording, isLoading = param.isLoading, collapseSendActions = param.collapseSendActions, uploadImage = param.uploadImage, startRecording = param.startRecording, stopRecording = param.stopRecording, sendMessage = param.sendMessage, setIsLoading = param.setIsLoading, onStop = param.onStop, setRightPadding = param.setRightPadding, baseCls = param.baseCls, hashId = param.hashId;
103
103
  return useMemo(function() {
104
104
  var _sendProps_attachment;
105
105
  return React.createElement(SendActions, {
@@ -117,6 +117,8 @@ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
117
117
  typing: sendProps.typing,
118
118
  isLoading: isLoading,
119
119
  fileUploadDone: fileUploadDone,
120
+ fileUploadStatus: fileUploadStatus,
121
+ fileUploadSummary: fileUploadSummary,
120
122
  recording: recording,
121
123
  collapseSendActions: collapseSendActions,
122
124
  allowEmptySubmit: sendProps.allowEmptySubmit,
@@ -151,6 +153,8 @@ import { MARKDOWN_INPUT_FIELD_TEST_IDS } from "../testIds";
151
153
  setFileMap,
152
154
  supportedFormat,
153
155
  fileUploadDone,
156
+ fileUploadStatus,
157
+ fileUploadSummary,
154
158
  recording,
155
159
  isLoading,
156
160
  collapseSendActions,
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  export interface AnimationConfig {
3
- /** 淡入动画持续时间(ms),默认 200 */
3
+ /** 淡入动画持续时间(ms),默认 250 */
4
4
  fadeDuration?: number;
5
- /** 缓动函数,默认 ease-in-out */
5
+ /** 缓动函数,默认 ease-out */
6
6
  easing?: string;
7
7
  }
8
8
  export interface AnimationTextProps {
@@ -12,11 +12,8 @@ export interface AnimationTextProps {
12
12
  /**
13
13
  * 流式文字淡入动画组件。
14
14
  *
15
- * 移植自 @ant-design/x-markdown AnimationText。
16
- * 追踪 children 的文本变化,只给新增的部分加淡入动画 span
17
- * 已有的部分保持不动——不会触发整段重绘。
18
- *
19
- * 仅对纯文本增量有效;如果内容不是简单追加(删除/替换),直接替换所有 chunks。
15
+ * 采用 opacity + translateY(GPU 硬件加速),清爽流派。
16
+ * 动画结束后通过 animationend 标记 done,仍用 span 包裹以保持布局稳定。
20
17
  */
21
18
  declare const AnimationText: React.NamedExoticComponent<AnimationTextProps>;
22
19
  export default AnimationText;
@@ -9,6 +9,19 @@ function _array_with_holes(arr) {
9
9
  function _array_without_holes(arr) {
10
10
  if (Array.isArray(arr)) return _array_like_to_array(arr);
11
11
  }
12
+ function _define_property(obj, key, value) {
13
+ if (key in obj) {
14
+ Object.defineProperty(obj, key, {
15
+ value: value,
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true
19
+ });
20
+ } else {
21
+ obj[key] = value;
22
+ }
23
+ return obj;
24
+ }
12
25
  function _iterable_to_array(iter) {
13
26
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
14
27
  }
@@ -42,6 +55,45 @@ function _non_iterable_rest() {
42
55
  function _non_iterable_spread() {
43
56
  throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
44
57
  }
58
+ function _object_spread(target) {
59
+ for(var i = 1; i < arguments.length; i++){
60
+ var source = arguments[i] != null ? arguments[i] : {};
61
+ var ownKeys = Object.keys(source);
62
+ if (typeof Object.getOwnPropertySymbols === "function") {
63
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
64
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
65
+ }));
66
+ }
67
+ ownKeys.forEach(function(key) {
68
+ _define_property(target, key, source[key]);
69
+ });
70
+ }
71
+ return target;
72
+ }
73
+ function ownKeys(object, enumerableOnly) {
74
+ var keys = Object.keys(object);
75
+ if (Object.getOwnPropertySymbols) {
76
+ var symbols = Object.getOwnPropertySymbols(object);
77
+ if (enumerableOnly) {
78
+ symbols = symbols.filter(function(sym) {
79
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
80
+ });
81
+ }
82
+ keys.push.apply(keys, symbols);
83
+ }
84
+ return keys;
85
+ }
86
+ function _object_spread_props(target, source) {
87
+ source = source != null ? source : {};
88
+ if (Object.getOwnPropertyDescriptors) {
89
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
90
+ } else {
91
+ ownKeys(Object(source)).forEach(function(key) {
92
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
93
+ });
94
+ }
95
+ return target;
96
+ }
45
97
  function _sliced_to_array(arr, i) {
46
98
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
47
99
  }
@@ -69,55 +121,105 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
69
121
  }
70
122
  return '';
71
123
  };
124
+ /**
125
+ * 识别 children 中是否包含 React 元素节点。
126
+ * 富文本结构(链接、脚注、图片等)在纯文本差分下会丢失结构信息,直接透传更安全。
127
+ */ var hasElementNode = function hasElementNode1(children) {
128
+ if (children === null || children === undefined || typeof children === 'boolean') return false;
129
+ if (typeof children === 'string' || typeof children === 'number') return false;
130
+ if (Array.isArray(children)) return children.some(hasElementNode);
131
+ return /*#__PURE__*/ React.isValidElement(children);
132
+ };
72
133
  /**
73
134
  * 流式文字淡入动画组件。
74
135
  *
75
- * 移植自 @ant-design/x-markdown AnimationText。
76
- * 追踪 children 的文本变化,只给新增的部分加淡入动画 span
77
- * 已有的部分保持不动——不会触发整段重绘。
78
- *
79
- * 仅对纯文本增量有效;如果内容不是简单追加(删除/替换),直接替换所有 chunks。
136
+ * 采用 opacity + translateY(GPU 硬件加速),清爽流派。
137
+ * 动画结束后通过 animationend 标记 done,仍用 span 包裹以保持布局稳定。
80
138
  */ var AnimationText = /*#__PURE__*/ React.memo(function(param) {
81
139
  var children = param.children, animationConfig = param.animationConfig;
82
- var _ref = animationConfig || {}, _ref_fadeDuration = _ref.fadeDuration, fadeDuration = _ref_fadeDuration === void 0 ? 200 : _ref_fadeDuration, _ref_easing = _ref.easing, easing = _ref_easing === void 0 ? 'ease-in-out' : _ref_easing;
140
+ var _ref = animationConfig || {}, _ref_fadeDuration = _ref.fadeDuration, fadeDuration = _ref_fadeDuration === void 0 ? 200 : _ref_fadeDuration, _ref_easing = _ref.easing, easing = _ref_easing === void 0 ? 'ease-out' : _ref_easing;
83
141
  var _useState = _sliced_to_array(useState([]), 2), chunks = _useState[0], setChunks = _useState[1];
84
142
  var prevTextRef = useRef('');
85
143
  var text = extractText(children);
144
+ var hasElementContent = hasElementNode(children);
86
145
  useEffect(function() {
146
+ if (hasElementContent) {
147
+ prevTextRef.current = text;
148
+ return;
149
+ }
87
150
  if (text === prevTextRef.current) return;
88
151
  if (!prevTextRef.current || !text.startsWith(prevTextRef.current)) {
89
152
  setChunks([
90
- children
153
+ {
154
+ key: '0',
155
+ text: text,
156
+ content: children,
157
+ done: false
158
+ }
91
159
  ]);
92
160
  prevTextRef.current = text;
93
161
  return;
94
162
  }
95
163
  var prevLen = prevTextRef.current.length;
164
+ var newText = text.slice(prevLen);
165
+ var newKey = "anim-".concat(Date.now(), "-").concat(prevLen);
96
166
  setChunks(function(prev) {
97
167
  return _to_consumable_array(prev).concat([
98
- text.slice(prevLen)
168
+ {
169
+ key: newKey,
170
+ text: newText,
171
+ done: false
172
+ }
99
173
  ]);
100
174
  });
101
175
  prevTextRef.current = text;
102
176
  }, [
103
177
  text,
104
- children
178
+ children,
179
+ hasElementContent
105
180
  ]);
181
+ var handleAnimationEnd = function handleAnimationEnd(key) {
182
+ setChunks(function(prev) {
183
+ return prev.map(function(c) {
184
+ return c.key === key ? _object_spread_props(_object_spread({}, c), {
185
+ done: true
186
+ }) : c;
187
+ });
188
+ });
189
+ };
106
190
  var animationStyle = useMemo(function() {
107
191
  return {
108
- animation: "markdownRendererFadeIn ".concat(fadeDuration, "ms ").concat(easing, " forwards"),
109
- willChange: 'opacity',
192
+ display: 'inline-block',
193
+ animation: "markdownRendererSlideFadeIn ".concat(fadeDuration, "ms ").concat(easing, " forwards"),
194
+ willChange: 'opacity, transform',
110
195
  color: 'inherit'
111
196
  };
112
197
  }, [
113
198
  fadeDuration,
114
199
  easing
115
200
  ]);
116
- return /*#__PURE__*/ React.createElement(React.Fragment, null, chunks.map(function(chunk, index) {
117
- return /*#__PURE__*/ React.createElement("span", {
201
+ /** 动画结束后仍用 inline-block 包裹,避免从 span 变为裸内容时的宽度重排 */ var doneChunkStyle = useMemo(function() {
202
+ return {
203
+ display: 'inline-block',
204
+ color: 'inherit'
205
+ };
206
+ }, []);
207
+ if (hasElementContent) {
208
+ return /*#__PURE__*/ React.createElement(React.Fragment, null, children);
209
+ }
210
+ return /*#__PURE__*/ React.createElement(React.Fragment, null, chunks.map(function(chunk) {
211
+ var _chunk_content;
212
+ var rendered = (_chunk_content = chunk.content) !== null && _chunk_content !== void 0 ? _chunk_content : chunk.text;
213
+ return chunk.done ? /*#__PURE__*/ React.createElement("span", {
214
+ key: chunk.key,
215
+ style: doneChunkStyle
216
+ }, rendered) : /*#__PURE__*/ React.createElement("span", {
217
+ key: chunk.key,
118
218
  style: animationStyle,
119
- key: "anim-".concat(index)
120
- }, chunk);
219
+ onAnimationEnd: function onAnimationEnd() {
220
+ return handleAnimationEnd(chunk.key);
221
+ }
222
+ }, rendered);
121
223
  }));
122
224
  });
123
225
  AnimationText.displayName = 'AnimationText';
@@ -138,13 +138,15 @@ import React, { forwardRef, useContext, useEffect, useImperativeHandle, useMemo,
138
138
  import { useStyle as useContentStyle } from "../MarkdownEditor/editor/style";
139
139
  import { useStyle as useEditorStyle } from "../MarkdownEditor/style";
140
140
  import { CharacterQueue } from "./CharacterQueue";
141
+ import { AgenticUiTaskBlockRenderer } from "./renderers/AgenticUiTaskBlockRenderer";
142
+ import { AgenticUiToolUseBarBlockRenderer } from "./renderers/AgenticUiToolUseBarBlockRenderer";
141
143
  import { ChartBlockRenderer } from "./renderers/ChartRenderer";
142
144
  import { CodeBlockRenderer } from "./renderers/CodeRenderer";
143
145
  import { MermaidBlockRenderer } from "./renderers/MermaidRenderer";
144
146
  import { SchemaBlockRenderer } from "./renderers/SchemaRenderer";
145
147
  import { useRendererVarStyle } from "./style";
146
- import { useStreaming } from "./useStreaming";
147
148
  import { useMarkdownToReact } from "./useMarkdownToReact";
149
+ import { useStreaming } from "./useStreaming";
148
150
  var SCHEMA_LANGUAGES = new Set([
149
151
  'schema',
150
152
  'apaasify',
@@ -201,6 +203,18 @@ var SCHEMA_LANGUAGES = new Set([
201
203
  language: language
202
204
  }));
203
205
  }
206
+ if (language === 'agentic-ui-task') {
207
+ var TaskComp = pluginComponents['agentic-ui-task'] || AgenticUiTaskBlockRenderer;
208
+ return /*#__PURE__*/ React.createElement(TaskComp, _object_spread_props(_object_spread({}, rest), {
209
+ language: language
210
+ }));
211
+ }
212
+ if (language === 'agentic-ui-toolusebar' || language === 'agentic-ui-usertoolbar') {
213
+ var ToolbarComp = pluginComponents['agentic-ui-toolusebar'] || pluginComponents['agentic-ui-usertoolbar'] || AgenticUiToolUseBarBlockRenderer;
214
+ return /*#__PURE__*/ React.createElement(ToolbarComp, _object_spread_props(_object_spread({}, rest), {
215
+ language: language
216
+ }));
217
+ }
204
218
  if (SCHEMA_LANGUAGES.has(language)) {
205
219
  var SchemaComp = pluginComponents.schema || SchemaBlockRenderer;
206
220
  return /*#__PURE__*/ React.createElement(SchemaComp, _object_spread_props(_object_spread({}, rest), {
@@ -1,3 +1,5 @@
1
+ export { default as AnimationText } from './AnimationText';
2
+ export type { AnimationConfig, AnimationTextProps } from './AnimationText';
1
3
  export { CharacterQueue } from './CharacterQueue';
2
4
  export { default as MarkdownRenderer } from './MarkdownRenderer';
3
5
  export { ChartBlockRenderer } from './renderers/ChartRenderer';
@@ -5,7 +7,5 @@ export { CodeBlockRenderer } from './renderers/CodeRenderer';
5
7
  export { MermaidBlockRenderer } from './renderers/MermaidRenderer';
6
8
  export { SchemaBlockRenderer } from './renderers/SchemaRenderer';
7
9
  export type { CharacterQueueOptions, MarkdownRendererProps, MarkdownRendererRef, RenderMode, RendererBlockProps, } from './types';
8
- export { default as AnimationText } from './AnimationText';
9
- export type { AnimationConfig, AnimationTextProps } from './AnimationText';
10
10
  export { markdownToReactSync, useMarkdownToReact } from './useMarkdownToReact';
11
11
  export { useStreaming } from './useStreaming';
@@ -1,9 +1,9 @@
1
+ export { default as AnimationText } from "./AnimationText";
1
2
  export { CharacterQueue } from "./CharacterQueue";
2
3
  export { default as MarkdownRenderer } from "./MarkdownRenderer";
3
4
  export { ChartBlockRenderer } from "./renderers/ChartRenderer";
4
5
  export { CodeBlockRenderer } from "./renderers/CodeRenderer";
5
6
  export { MermaidBlockRenderer } from "./renderers/MermaidRenderer";
6
7
  export { SchemaBlockRenderer } from "./renderers/SchemaRenderer";
7
- export { default as AnimationText } from "./AnimationText";
8
8
  export { markdownToReactSync, useMarkdownToReact } from "./useMarkdownToReact";
9
9
  export { useStreaming } from "./useStreaming";
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import type { RendererBlockProps } from '../types';
3
+ /**
4
+ * ```agentic-ui-task``` 代码块 → TaskList(与 MarkdownEditor parseCode 对齐)
5
+ */
6
+ export declare const AgenticUiTaskBlockRenderer: React.FC<RendererBlockProps>;
@@ -0,0 +1,66 @@
1
+ import json5 from "json5";
2
+ import React, { useMemo } from "react";
3
+ import { normalizeTaskListPropsFromJson } from "../../MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils";
4
+ import partialParse from "../../MarkdownEditor/editor/parser/json-parse";
5
+ import { TaskList } from "../../TaskList";
6
+ var extractTextContent = function extractTextContent1(children) {
7
+ var _children_props;
8
+ if (typeof children === 'string') return children;
9
+ if (typeof children === 'number') return String(children);
10
+ if (Array.isArray(children)) return children.map(extractTextContent).join('');
11
+ if (/*#__PURE__*/ React.isValidElement(children) && ((_children_props = children.props) === null || _children_props === void 0 ? void 0 : _children_props.children)) {
12
+ return extractTextContent(children.props.children);
13
+ }
14
+ return '';
15
+ };
16
+ var parseJsonBody = function parseJsonBody(code) {
17
+ try {
18
+ return json5.parse(code || '{}');
19
+ } catch (unused) {
20
+ try {
21
+ return partialParse(code || '{}');
22
+ } catch (unused) {
23
+ return null;
24
+ }
25
+ }
26
+ };
27
+ /**
28
+ * ```agentic-ui-task``` 代码块 → TaskList(与 MarkdownEditor parseCode 对齐)
29
+ */ export var AgenticUiTaskBlockRenderer = function AgenticUiTaskBlockRenderer(props) {
30
+ var code = useMemo(function() {
31
+ return extractTextContent(props.children);
32
+ }, [
33
+ props.children
34
+ ]);
35
+ var parsed = useMemo(function() {
36
+ return parseJsonBody(code);
37
+ }, [
38
+ code
39
+ ]);
40
+ var listProps = useMemo(function() {
41
+ return normalizeTaskListPropsFromJson(parsed);
42
+ }, [
43
+ parsed
44
+ ]);
45
+ if (parsed === null) {
46
+ return /*#__PURE__*/ React.createElement("pre", {
47
+ "data-testid": "agentic-ui-task-fallback",
48
+ style: {
49
+ background: 'rgb(242, 241, 241)',
50
+ padding: '1em',
51
+ borderRadius: '0.5em',
52
+ margin: '0.75em 0',
53
+ fontSize: '0.8em',
54
+ whiteSpace: 'pre-wrap',
55
+ wordBreak: 'break-all'
56
+ }
57
+ }, /*#__PURE__*/ React.createElement("code", null, code));
58
+ }
59
+ return /*#__PURE__*/ React.createElement("div", {
60
+ "data-testid": "agentic-ui-task-block",
61
+ style: {
62
+ margin: '0.75em 0'
63
+ }
64
+ }, /*#__PURE__*/ React.createElement(TaskList, listProps));
65
+ };
66
+ AgenticUiTaskBlockRenderer.displayName = 'AgenticUiTaskBlockRenderer';
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import type { RendererBlockProps } from '../types';
3
+ /**
4
+ * ```agentic-ui-toolusebar``` 代码块 → ToolUseBar
5
+ */
6
+ export declare const AgenticUiToolUseBarBlockRenderer: React.FC<RendererBlockProps>;
@@ -0,0 +1,134 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
14
+ function _object_spread(target) {
15
+ for(var i = 1; i < arguments.length; i++){
16
+ var source = arguments[i] != null ? arguments[i] : {};
17
+ var ownKeys = Object.keys(source);
18
+ if (typeof Object.getOwnPropertySymbols === "function") {
19
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
20
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
21
+ }));
22
+ }
23
+ ownKeys.forEach(function(key) {
24
+ _define_property(target, key, source[key]);
25
+ });
26
+ }
27
+ return target;
28
+ }
29
+ function _object_without_properties(source, excluded) {
30
+ if (source == null) return {};
31
+ var target = {}, sourceKeys, key, i;
32
+ if (typeof Reflect !== "undefined" && Reflect.ownKeys) {
33
+ sourceKeys = Reflect.ownKeys(source);
34
+ for(i = 0; i < sourceKeys.length; i++){
35
+ key = sourceKeys[i];
36
+ if (excluded.indexOf(key) >= 0) continue;
37
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
38
+ target[key] = source[key];
39
+ }
40
+ return target;
41
+ }
42
+ target = _object_without_properties_loose(source, excluded);
43
+ if (Object.getOwnPropertySymbols) {
44
+ sourceKeys = Object.getOwnPropertySymbols(source);
45
+ for(i = 0; i < sourceKeys.length; i++){
46
+ key = sourceKeys[i];
47
+ if (excluded.indexOf(key) >= 0) continue;
48
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
49
+ target[key] = source[key];
50
+ }
51
+ }
52
+ return target;
53
+ }
54
+ function _object_without_properties_loose(source, excluded) {
55
+ if (source == null) return {};
56
+ var target = {}, sourceKeys = Object.getOwnPropertyNames(source), key, i;
57
+ for(i = 0; i < sourceKeys.length; i++){
58
+ key = sourceKeys[i];
59
+ if (excluded.indexOf(key) >= 0) continue;
60
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
61
+ target[key] = source[key];
62
+ }
63
+ return target;
64
+ }
65
+ import json5 from "json5";
66
+ import React, { useMemo } from "react";
67
+ import { normalizeToolUseBarPropsFromJson } from "../../MarkdownEditor/editor/elements/AgenticUiBlocks/agenticUiEmbedUtils";
68
+ import partialParse from "../../MarkdownEditor/editor/parser/json-parse";
69
+ import { ToolUseBar } from "../../ToolUseBar";
70
+ var extractTextContent = function extractTextContent1(children) {
71
+ var _children_props;
72
+ if (typeof children === 'string') return children;
73
+ if (typeof children === 'number') return String(children);
74
+ if (Array.isArray(children)) return children.map(extractTextContent).join('');
75
+ if (/*#__PURE__*/ React.isValidElement(children) && ((_children_props = children.props) === null || _children_props === void 0 ? void 0 : _children_props.children)) {
76
+ return extractTextContent(children.props.children);
77
+ }
78
+ return '';
79
+ };
80
+ var parseJsonBody = function parseJsonBody(code) {
81
+ try {
82
+ return json5.parse(code || '{}');
83
+ } catch (unused) {
84
+ try {
85
+ return partialParse(code || '{}');
86
+ } catch (unused) {
87
+ return null;
88
+ }
89
+ }
90
+ };
91
+ /**
92
+ * ```agentic-ui-toolusebar``` 代码块 → ToolUseBar
93
+ */ export var AgenticUiToolUseBarBlockRenderer = function AgenticUiToolUseBarBlockRenderer(props) {
94
+ var code = useMemo(function() {
95
+ return extractTextContent(props.children);
96
+ }, [
97
+ props.children
98
+ ]);
99
+ var parsed = useMemo(function() {
100
+ return parseJsonBody(code);
101
+ }, [
102
+ code
103
+ ]);
104
+ var _useMemo = useMemo(function() {
105
+ return normalizeToolUseBarPropsFromJson(parsed);
106
+ }, [
107
+ parsed
108
+ ]), tools = _useMemo.tools, restBar = _object_without_properties(_useMemo, [
109
+ "tools"
110
+ ]);
111
+ if (parsed === null) {
112
+ return /*#__PURE__*/ React.createElement("pre", {
113
+ "data-testid": "agentic-ui-toolusebar-fallback",
114
+ style: {
115
+ background: 'rgb(242, 241, 241)',
116
+ padding: '1em',
117
+ borderRadius: '0.5em',
118
+ margin: '0.75em 0',
119
+ fontSize: '0.8em',
120
+ whiteSpace: 'pre-wrap',
121
+ wordBreak: 'break-all'
122
+ }
123
+ }, /*#__PURE__*/ React.createElement("code", null, code));
124
+ }
125
+ return /*#__PURE__*/ React.createElement("div", {
126
+ "data-testid": "agentic-ui-toolusebar-block",
127
+ style: {
128
+ margin: '0.75em 0'
129
+ }
130
+ }, /*#__PURE__*/ React.createElement(ToolUseBar, _object_spread({
131
+ tools: tools
132
+ }, restBar)));
133
+ };
134
+ AgenticUiToolUseBarBlockRenderer.displayName = 'AgenticUiToolUseBarBlockRenderer';