@ant-design/agentic-ui 2.29.8 → 2.29.10

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.
@@ -101,7 +101,8 @@ import { MessagesContext } from "./BubbleContext";
101
101
  useEffect(function() {
102
102
  if (isFinished) {
103
103
  var _MarkdownEditorRef_current;
104
- (_MarkdownEditorRef_current = MarkdownEditorRef.current) === null || _MarkdownEditorRef_current === void 0 ? void 0 : _MarkdownEditorRef_current.store.setMDContent(content);
104
+ console.log('content', content);
105
+ (_MarkdownEditorRef_current = MarkdownEditorRef.current) === null || _MarkdownEditorRef_current === void 0 ? void 0 : _MarkdownEditorRef_current.store.setContent(parserMdToSchema(content).schema);
105
106
  return;
106
107
  }
107
108
  }, [
@@ -115,6 +116,7 @@ import { MessagesContext } from "./BubbleContext";
115
116
  ]);
116
117
  useEffect(function() {
117
118
  var _MarkdownEditorRef_current;
119
+ console.log("updatecontent", content);
118
120
  var schema = parserMdToSchema(content).schema;
119
121
  (_MarkdownEditorRef_current = MarkdownEditorRef.current) === null || _MarkdownEditorRef_current === void 0 ? void 0 : _MarkdownEditorRef_current.store.updateNodeList(schema);
120
122
  }, [
@@ -167,37 +167,16 @@ export var BackspaceKey = /*#__PURE__*/ function() {
167
167
  var _parent_1;
168
168
  var parent1 = Editor.parent(this.editor, path);
169
169
  if ((parent1 === null || parent1 === void 0 ? void 0 : (_parent_1 = parent1[0]) === null || _parent_1 === void 0 ? void 0 : _parent_1.type) === 'list-item') {
170
- // 处理行首 Backspace 减少缩进
171
- if (Range.isCollapsed(sel) && sel.anchor.offset === 0) {
172
- var listItemPath = parent1[1];
173
- var listPath = Path.parent(listItemPath);
174
- var list = Node.get(this.editor, listPath);
175
- if (isListType(list)) {
176
- var listParent = Editor.parent(this.editor, listPath);
177
- // 如果父节点是 list-item,说明在嵌套列表中,可以提升
178
- if (Element.isElement(listParent[0]) && listParent[0].type === 'list-item') {
179
- // 使用 liftNodes 提升当前 list-item
180
- Transforms.liftNodes(this.editor, {
181
- at: listItemPath
182
- });
183
- // 如果提升后,原列表为空,需要删除空列表
184
- var updatedList = Node.get(this.editor, listPath);
185
- if (isListType(updatedList) && updatedList.children.length === 0) {
186
- Transforms.removeNodes(this.editor, {
187
- at: listPath
188
- });
189
- }
190
- return true;
191
- }
192
- }
193
- }
194
- if (Node.string(parent1[0]) !== '') {
195
- return false;
196
- }
197
- if (Node.string(parent1[0]) === '') {
170
+ // 先检查 list-item 是否为空:检查第一个段落(子节点)是否为空
171
+ var listItem = parent1[0];
172
+ var firstChild = Element.isElement(listItem) && listItem.children.length > 0 ? listItem.children[0] : null;
173
+ var isEmptyListItem = firstChild && Element.isElement(firstChild) && firstChild.type === 'paragraph' && Node.string(firstChild).trim() === '' && listItem.children.length === 1; // 只有第一个段落,没有嵌套列表
174
+ console.log('isEmptyListItem', isEmptyListItem);
175
+ // 如果 list-item 为空,优先执行删除逻辑
176
+ if (isEmptyListItem) {
198
177
  // 使用新的拆分逻辑处理空的list-item
199
- var listPath1 = Path.parent(parent1[1]);
200
- var listNode = Editor.node(this.editor, listPath1);
178
+ var listPath = Path.parent(parent1[1]);
179
+ var listNode = Editor.node(this.editor, listPath);
201
180
  var currentItemIndex = parent1[1][parent1[1].length - 1];
202
181
  var isLastItem = currentItemIndex === listNode[0].children.length - 1;
203
182
  if (isLastItem) {
@@ -207,10 +186,10 @@ export var BackspaceKey = /*#__PURE__*/ function() {
207
186
  at: parent1[1]
208
187
  });
209
188
  // 如果列表为空,删除列表容器
210
- var updatedList1 = Node.get(this.editor, listPath1);
211
- if (isListType(updatedList1) && updatedList1.children.length === 0) {
189
+ var updatedList = Node.get(this.editor, listPath);
190
+ if (isListType(updatedList) && Node.string(updatedList).trim() === '') {
212
191
  Transforms.removeNodes(this.editor, {
213
- at: listPath1
192
+ at: listPath
214
193
  });
215
194
  // 在列表位置插入 paragraph
216
195
  Transforms.insertNodes(this.editor, {
@@ -221,7 +200,7 @@ export var BackspaceKey = /*#__PURE__*/ function() {
221
200
  }
222
201
  ]
223
202
  }, {
224
- at: listPath1,
203
+ at: listPath,
225
204
  select: true
226
205
  });
227
206
  } else {
@@ -243,7 +222,7 @@ export var BackspaceKey = /*#__PURE__*/ function() {
243
222
  // 先删除后面的 items(从后往前删除,避免索引变化)
244
223
  for(var i = listNode[0].children.length - 1; i > currentItemIndex; i--){
245
224
  Transforms.removeNodes(this.editor, {
246
- at: _to_consumable_array(listPath1).concat([
225
+ at: _to_consumable_array(listPath).concat([
247
226
  i
248
227
  ])
249
228
  });
@@ -253,11 +232,11 @@ export var BackspaceKey = /*#__PURE__*/ function() {
253
232
  at: parent1[1]
254
233
  });
255
234
  // 检查列表是否为空,如果为空则删除列表容器
256
- var updatedList2 = Node.get(this.editor, listPath1);
257
- if (isListType(updatedList2) && updatedList2.children.length === 0) {
235
+ var updatedList1 = Node.get(this.editor, listPath);
236
+ if (isListType(updatedList1) && Node.string(updatedList1).trim() === '') {
258
237
  // 列表为空,删除列表容器
259
238
  Transforms.removeNodes(this.editor, {
260
- at: listPath1
239
+ at: listPath
261
240
  });
262
241
  // 在列表位置插入 paragraph
263
242
  Transforms.insertNodes(this.editor, {
@@ -268,13 +247,13 @@ export var BackspaceKey = /*#__PURE__*/ function() {
268
247
  }
269
248
  ]
270
249
  }, {
271
- at: listPath1,
250
+ at: listPath,
272
251
  select: true
273
252
  });
274
253
  } else {
275
254
  // 列表还有前面的 items,保持列表
276
255
  // 在列表后插入 paragraph
277
- var insertPath = Path.next(listPath1);
256
+ var insertPath = Path.next(listPath);
278
257
  Transforms.insertNodes(this.editor, {
279
258
  type: 'paragraph',
280
259
  children: [
@@ -290,6 +269,31 @@ export var BackspaceKey = /*#__PURE__*/ function() {
290
269
  }
291
270
  return true;
292
271
  }
272
+ // 如果 list-item 不为空,处理行首 Backspace 减少缩进
273
+ if (Range.isCollapsed(sel) && sel.anchor.offset === 0) {
274
+ var listItemPath = parent1[1];
275
+ var listPath1 = Path.parent(listItemPath);
276
+ var list = Node.get(this.editor, listPath1);
277
+ if (isListType(list)) {
278
+ var listParent = Editor.parent(this.editor, listPath1);
279
+ // 如果父节点是 list-item,说明在嵌套列表中,可以提升
280
+ if (listParent && listParent[0] && Element.isElement(listParent[0]) && listParent[0].type === 'list-item') {
281
+ // 使用 liftNodes 提升当前 list-item
282
+ Transforms.liftNodes(this.editor, {
283
+ at: listItemPath
284
+ });
285
+ // 如果提升后,原列表为空,需要删除空列表
286
+ var updatedList2 = Node.get(this.editor, listPath1);
287
+ if (isListType(updatedList2) && Node.string(updatedList2).trim() === '') {
288
+ Transforms.removeNodes(this.editor, {
289
+ at: listPath1
290
+ });
291
+ }
292
+ return true;
293
+ }
294
+ }
295
+ }
296
+ return false;
293
297
  }
294
298
  }
295
299
  /**
@@ -299,6 +299,8 @@ export var EnterKey = /*#__PURE__*/ function() {
299
299
  });
300
300
  } else if (!Path.hasPrevious(path)) {
301
301
  e.preventDefault();
302
+ // 在列表项开头按回车时,只创建新的空列表项,不移动任何节点
303
+ // 这样可以避免将嵌套列表或其他节点移动到新列表项内部,导致缩进
302
304
  Transforms.insertNodes(this.editor, {
303
305
  type: 'list-item',
304
306
  checked: typeof parent.checked === 'boolean' ? false : undefined,
@@ -309,9 +311,6 @@ export var EnterKey = /*#__PURE__*/ function() {
309
311
  at: Path.next(parentPath),
310
312
  select: true
311
313
  });
312
- var cur = Path.next(path);
313
- var index = 1;
314
- EditorUtils.moveNodes(this.editor, cur, Path.next(parentPath), index);
315
314
  }
316
315
  }
317
316
  }
@@ -575,9 +574,8 @@ export var EnterKey = /*#__PURE__*/ function() {
575
574
  if (Editor.start(this.editor, Path.next(parent[1]))) {
576
575
  Transforms.select(this.editor, Editor.start(this.editor, Path.next(parent[1])));
577
576
  }
578
- if (Editor.hasPath(this.editor, Path.next(node[1]))) {
579
- EditorUtils.moveNodes(this.editor, Path.next(node[1]), Path.next(parent[1]), 1);
580
- }
577
+ // 不再移动任何节点到新列表项内部,避免导致新列表项被缩进
578
+ // 嵌套列表应该保留在原列表项中
581
579
  return true;
582
580
  }
583
581
  }
@@ -89,7 +89,7 @@ function _unsupported_iterable_to_array(o, minLen) {
89
89
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
90
90
  }
91
91
  import { Editor, Element, Node, Path, Point, Range, Text, Transforms } from "slate";
92
- import { isListType, getListType } from "../withListsPlugin";
92
+ import { getListType, isListType } from "../withListsPlugin";
93
93
  /**
94
94
  * TabKey 类用于处理编辑器中的 Tab 键事件。
95
95
  */ export var TabKey = /*#__PURE__*/ function() {
@@ -235,7 +235,7 @@ import { isListType, getListType } from "../withListsPlugin";
235
235
  key: "listItem",
236
236
  value: /**
237
237
  * 处理列表项的 Tab/Shift+Tab 键
238
- *
238
+ *
239
239
  * Tab: 增加缩进(将当前 list-item 移动到前一个 list-item 的子列表中)
240
240
  * Shift+Tab: 减少缩进(将当前 list-item 提升一级)
241
241
  */ function listItem(node, e) {
@@ -347,7 +347,7 @@ import { isListType, getListType } from "../withListsPlugin";
347
347
  });
348
348
  // 如果提升后,原列表为空,需要删除空列表
349
349
  var updatedList = Node.get(this.editor, listPath);
350
- if (isListType(updatedList) && updatedList.children.length === 0) {
350
+ if (isListType(updatedList) && Node.string(updatedList).trim() === '') {
351
351
  Transforms.removeNodes(this.editor, {
352
352
  at: listPath
353
353
  });
@@ -1,9 +1,9 @@
1
- export * from './withMarkdown';
2
- export * from './withInlineNodes';
3
- export * from './withVoidNodes';
1
+ export * from './utils';
4
2
  export * from './withCardPlugin';
3
+ export * from './withCodeTagPlugin';
4
+ export * from './withInlineNodes';
5
5
  export * from './withLinkAndMediaPlugin';
6
6
  export * from './withListsPlugin';
7
+ export * from './withMarkdown';
7
8
  export * from './withSchemaPlugin';
8
- export * from './withCodeTagPlugin';
9
- export * from './utils';
9
+ export * from './withVoidNodes';
@@ -1,9 +1,9 @@
1
- export * from "./withMarkdown";
2
- export * from "./withInlineNodes";
3
- export * from "./withVoidNodes";
1
+ export * from "./utils";
4
2
  export * from "./withCardPlugin";
3
+ export * from "./withCodeTagPlugin";
4
+ export * from "./withInlineNodes";
5
5
  export * from "./withLinkAndMediaPlugin";
6
6
  export * from "./withListsPlugin";
7
+ export * from "./withMarkdown";
7
8
  export * from "./withSchemaPlugin";
8
- export * from "./withCodeTagPlugin";
9
- export * from "./utils";
9
+ export * from "./withVoidNodes";
@@ -197,30 +197,49 @@ import { useEditorStore } from "../store";
197
197
  enter.run(e);
198
198
  return;
199
199
  }
200
- // Enter 键(无 Shift)由 MarkdownInputField 处理发送,这里不处理
200
+ // Enter 键(无 Shift)处理:如果在列表项中,让 EnterKey 处理;否则由 MarkdownInputField 处理发送
201
201
  if (e.key === 'Enter' && !(e.ctrlKey || e.metaKey) && !e.shiftKey) {
202
+ // 检查当前是否在列表项中
203
+ var selection1 = markdownEditorRef.current.selection;
204
+ if (selection1 && Range.isCollapsed(selection1)) {
205
+ var _Editor_nodes1 = _sliced_to_array(Editor.nodes(markdownEditorRef.current, {
206
+ at: selection1.focus.path,
207
+ match: function(n) {
208
+ return Element.isElement(n) && n.type === 'list-item';
209
+ },
210
+ mode: 'lowest'
211
+ }), 1), node1 = _Editor_nodes1[0];
212
+ if (node1) {
213
+ // 在列表项中,让 EnterKey 处理
214
+ e.stopPropagation();
215
+ e.preventDefault();
216
+ enter.run(e);
217
+ return;
218
+ }
219
+ }
220
+ // 不在列表项中,让 MarkdownInputField 处理发送
202
221
  return;
203
222
  }
204
- var _Editor_nodes1 = _sliced_to_array(Editor.nodes(markdownEditorRef.current, {
223
+ var _Editor_nodes2 = _sliced_to_array(Editor.nodes(markdownEditorRef.current, {
205
224
  match: function(n) {
206
225
  return Element.isElement(n);
207
226
  },
208
227
  mode: 'lowest'
209
- }), 1), node1 = _Editor_nodes1[0];
210
- if (!node1) return;
211
- if ((node1 === null || node1 === void 0 ? void 0 : (_node_ = node1[0]) === null || _node_ === void 0 ? void 0 : _node_.type) === 'paragraph') {
212
- var _Editor_nodes2 = _sliced_to_array(Editor.nodes(markdownEditorRef.current, {
228
+ }), 1), node2 = _Editor_nodes2[0];
229
+ if (!node2) return;
230
+ if ((node2 === null || node2 === void 0 ? void 0 : (_node_ = node2[0]) === null || _node_ === void 0 ? void 0 : _node_.type) === 'paragraph') {
231
+ var _Editor_nodes3 = _sliced_to_array(Editor.nodes(markdownEditorRef.current, {
213
232
  match: function(n) {
214
233
  return Element.isElement(n) && n.type === 'paragraph';
215
234
  },
216
235
  mode: 'lowest'
217
- }), 1), node2 = _Editor_nodes2[0];
218
- if (node2 && node2[0].children.length === 1 && !EditorUtils.isDirtLeaf(node2[0].children[0]) && (e.key === 'Backspace' || /^[^\n]$/.test(e.key))) {
219
- var str = Node.string(node2[0]) || '';
236
+ }), 1), node3 = _Editor_nodes3[0];
237
+ if (node3 && node3[0].children.length === 1 && !EditorUtils.isDirtLeaf(node3[0].children[0]) && (e.key === 'Backspace' || /^[^\n]$/.test(e.key))) {
238
+ var str = Node.string(node3[0]) || '';
220
239
  var codeMatch = str.match(/^```([\w+\-#]+)$/i);
221
240
  if (codeMatch) {} else {
222
241
  var insertMatch = str.match(/^\/([^\n]+)?$/i);
223
- if (insertMatch && !(!Path.hasPrevious(node2[1]) && Node.parent(markdownEditorRef.current, node2[1]).type === 'list-item')) {
242
+ if (insertMatch && !(!Path.hasPrevious(node3[1]) && Node.parent(markdownEditorRef.current, node3[1]).type === 'list-item')) {
224
243
  setOpenInsertCompletion === null || setOpenInsertCompletion === void 0 ? void 0 : setOpenInsertCompletion(true);
225
244
  setTimeout(function() {
226
245
  insertCompletionText$.next(insertMatch[1]);
@@ -204,17 +204,6 @@ export declare class EditorStore {
204
204
  * @private
205
205
  */
206
206
  private _parseAndSetContentWithRAF;
207
- /**
208
- * 使用 requestAnimationFrame 分批设置内容
209
- * 每帧插入一批节点,避免长时间阻塞主线程
210
- *
211
- * @param allNodes - 所有要插入的节点
212
- * @param batchSize - 每帧处理的节点数量
213
- * @param onProgress - 进度回调函数
214
- * @returns Promise,在所有节点插入完成后 resolve
215
- * @private
216
- */
217
- private _setContentWithRAF;
218
207
  /**
219
208
  * 按指定分隔符拆分 markdown 内容
220
209
  * 保持内容结构的完整性
@@ -648,64 +648,6 @@ export var EditorStoreContext = createContext(null);
648
648
  });
649
649
  }
650
650
  },
651
- {
652
- key: "_setContentWithRAF",
653
- value: /**
654
- * 使用 requestAnimationFrame 分批设置内容
655
- * 每帧插入一批节点,避免长时间阻塞主线程
656
- *
657
- * @param allNodes - 所有要插入的节点
658
- * @param batchSize - 每帧处理的节点数量
659
- * @param onProgress - 进度回调函数
660
- * @returns Promise,在所有节点插入完成后 resolve
661
- * @private
662
- */ function _setContentWithRAF(allNodes, batchSize, onProgress) {
663
- var _this = this;
664
- return new Promise(function(resolve, reject) {
665
- var currentIndex = 0;
666
- var totalNodes = allNodes.length;
667
- var rafId = null;
668
- var insertBatch = function() {
669
- try {
670
- var endIndex = Math.min(currentIndex + batchSize, totalNodes);
671
- var batch = allNodes.slice(currentIndex, endIndex);
672
- if (currentIndex === 0) {
673
- // 第一批:清空并插入
674
- _this._editor.current.children = batch;
675
- _this._editor.current.onChange();
676
- } else {
677
- var // 后续批次:追加节点
678
- _this__editor_current_children;
679
- (_this__editor_current_children = _this._editor.current.children).push.apply(_this__editor_current_children, _to_consumable_array(batch));
680
- _this._editor.current.onChange();
681
- }
682
- currentIndex = endIndex;
683
- var progress = currentIndex / totalNodes;
684
- // 直接调用进度回调,避免嵌套 requestAnimationFrame
685
- onProgress === null || onProgress === void 0 ? void 0 : onProgress(progress);
686
- if (currentIndex < totalNodes) {
687
- // 还有节点未处理,继续下一帧
688
- rafId = requestAnimationFrame(insertBatch);
689
- } else {
690
- // 所有节点处理完成
691
- ReactEditor.deselect(_this._editor.current);
692
- rafId = null;
693
- resolve();
694
- }
695
- } catch (error) {
696
- // 清理资源并拒绝 Promise
697
- if (rafId) {
698
- cancelAnimationFrame(rafId);
699
- rafId = null;
700
- }
701
- reject(error);
702
- }
703
- };
704
- // 开始第一帧
705
- rafId = requestAnimationFrame(insertBatch);
706
- });
707
- }
708
- },
709
651
  {
710
652
  key: "_splitMarkdown",
711
653
  value: /**
@@ -952,67 +894,17 @@ export var EditorStoreContext = createContext(null);
952
894
  * @param nodeList - 要设置为编辑器内容的节点列表
953
895
  */ key: "setContent",
954
896
  value: function setContent(nodeList) {
955
- var _this = this;
956
897
  var currentChildren = this._editor.current.children;
957
- var resultChildren = [];
958
- // 逐个比较节点,如果 hash 和 finished 相同就保留旧节点,否则使用新节点
959
- for(var i = 0; i < nodeList.length; i++){
960
- var newNode = nodeList[i];
961
- var oldNode = currentChildren[i];
962
- // 如果旧节点不存在,直接使用新节点
963
- if (!oldNode) {
964
- resultChildren.push(newNode);
965
- continue;
966
- }
967
- // 如果 hash 和 finished 都相同,保留旧节点,继续处理下一个
968
- if (this._isNodeEqual(newNode, oldNode)) {
969
- resultChildren.push(oldNode);
970
- continue;
971
- }
972
- // hash 或 finished 不相同,使用新节点替换
973
- resultChildren.push(newNode);
974
- }
975
- // 使用批处理模式执行所有操作
976
- Editor.withoutNormalizing(this._editor.current, function() {
977
- // 先删除多余的节点(从后往前删除,避免索引变化)
978
- if (currentChildren.length > resultChildren.length) {
979
- for(var i = currentChildren.length - 1; i >= resultChildren.length; i--){
980
- Transforms.removeNodes(_this._editor.current, {
981
- at: [
982
- i
983
- ]
984
- });
985
- }
986
- }
987
- // 然后逐个替换或插入节点(从前往后处理)
988
- for(var i1 = 0; i1 < resultChildren.length; i1++){
989
- var newNode = resultChildren[i1];
990
- var oldNode = currentChildren[i1];
991
- if (!oldNode) {
992
- // 旧节点不存在,插入新节点
993
- Transforms.insertNodes(_this._editor.current, newNode, {
994
- at: [
995
- i1
996
- ]
997
- });
998
- } else if (oldNode !== newNode) {
999
- // 节点不同,替换节点
1000
- _this._replaceNodeAt([
1001
- i1
1002
- ], newNode);
1003
- }
1004
- // 如果 oldNode === newNode,说明是同一个对象引用,不需要更新
1005
- }
1006
- });
898
+ this._editor.current.children = nodeList;
1007
899
  this._editor.current.onChange();
1008
900
  // 检查最后一个节点是否以换行符结尾
1009
- var lastNode = resultChildren[resultChildren.length - 1];
901
+ var lastNode = currentChildren[currentChildren.length - 1];
1010
902
  if (lastNode && Text.isText(lastNode)) {
1011
903
  var text = Node.string(lastNode);
1012
904
  if (!text.endsWith('\n')) {
1013
905
  this._editor.current.insertText('\n', {
1014
906
  at: [
1015
- resultChildren.length - 1
907
+ currentChildren.length - 1
1016
908
  ]
1017
909
  });
1018
910
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ant-design/agentic-ui",
3
- "version": "2.29.8",
3
+ "version": "2.29.10",
4
4
  "description": "面向智能体的 UI 组件库,提供多步推理可视化、工具调用展示、任务执行协同等 Agentic UI 能力",
5
5
  "repository": "git@github.com:ant-design/agentic-ui.git",
6
6
  "license": "MIT",
@@ -22,12 +22,11 @@
22
22
  "lint:css": "stylelint \"{src,test}/**/*.{css,less}\"",
23
23
  "lint:es": "eslint \"{src,test}/**/*.{js,jsx,ts,tsx}\"",
24
24
  "prepare": "husky install && dumi setup",
25
- "prepublishOnly": "father doctor && pnpm run test && pnpm run build",
26
25
  "prettier": "prettier --write \"{src,docs,test}/**/*.{js,jsx,ts,tsx,css,less,json,md}\"",
27
26
  "preview": "pnpm dumi preview",
28
27
  "report:demo": "node scripts/generateDemoReport.js",
29
28
  "start": "pnpm run dev",
30
- "test": "echo \"Error: no test specified\" ",
29
+ "test": "vitest --run --exclude \"**/e2e/**\"",
31
30
  "test:coverage": "vitest --run --exclude \"**/e2e/**\" --coverage",
32
31
  "test:e2e": "playwright test",
33
32
  "test:e2e:debug": "playwright test --debug",