@ant-design/agentic-ui 2.30.30 → 2.30.31

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 (50) hide show
  1. package/dist/Bubble/AIBubble.js +6 -3
  2. package/dist/Bubble/List/PureBubbleList.js +22 -1
  3. package/dist/Bubble/List/index.js +7 -5
  4. package/dist/Bubble/MessagesContent/BubbleExtra.js +4 -2
  5. package/dist/Components/ActionIconBox/index.js +8 -8
  6. package/dist/Hooks/useLanguage.d.ts +1 -0
  7. package/dist/I18n/locales.d.ts +1 -0
  8. package/dist/I18n/locales.js +2 -0
  9. package/dist/MarkdownEditor/editor/parser/parse/parseHtml.js +15 -6
  10. package/dist/MarkdownEditor/style.js +0 -4
  11. package/dist/MarkdownInputField/SendButton/index.d.ts +2 -2
  12. package/dist/MarkdownInputField/SendButton/index.js +44 -26
  13. package/dist/MarkdownInputField/SendButton/sendButtonPalette.d.ts +36 -0
  14. package/dist/MarkdownInputField/SendButton/sendButtonPalette.js +247 -0
  15. package/dist/MarkdownInputField/SendButton/style.js +3 -3
  16. package/dist/MarkdownInputField/style.js +3 -1
  17. package/dist/MarkdownRenderer/AnimationText.js +1 -2
  18. package/dist/MarkdownRenderer/CharacterQueue.js +3 -0
  19. package/dist/MarkdownRenderer/MarkdownRenderer.js +5 -18
  20. package/dist/MarkdownRenderer/markdownReactShared.d.ts +2 -1
  21. package/dist/MarkdownRenderer/markdownReactShared.js +57 -19
  22. package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.js +14 -10
  23. package/dist/MarkdownRenderer/streaming/fenceTracker.d.ts +7 -0
  24. package/dist/MarkdownRenderer/streaming/fenceTracker.js +28 -0
  25. package/dist/MarkdownRenderer/streaming/lastBlockThrottle.js +3 -1
  26. package/dist/MarkdownRenderer/streaming/useShallowMemo.d.ts +1 -0
  27. package/dist/MarkdownRenderer/streaming/useShallowMemo.js +36 -0
  28. package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +6 -3
  29. package/dist/MarkdownRenderer/useStreaming.js +43 -41
  30. package/dist/Plugins/chart/components/ChartContainer/ChartErrorBoundary.d.ts +2 -0
  31. package/dist/TaskList/TaskList.js +25 -13
  32. package/dist/TaskList/constants.d.ts +1 -1
  33. package/dist/TaskList/constants.js +9 -4
  34. package/dist/TaskList/style.js +29 -11
  35. package/dist/ToolUseBarThink/index.d.ts +0 -23
  36. package/dist/ToolUseBarThink/index.js +178 -315
  37. package/dist/ToolUseBarThink/style.js +64 -48
  38. package/dist/Types/quicklink.d.ts +1 -1
  39. package/dist/Workspace/File/FileTree/FileTreeComponent.d.ts +4 -0
  40. package/dist/Workspace/File/FileTree/FileTreeComponent.js +283 -0
  41. package/dist/Workspace/File/FileTree/index.d.ts +2 -0
  42. package/dist/Workspace/File/FileTree/index.js +1 -0
  43. package/dist/Workspace/File/FileTree/style.d.ts +8 -0
  44. package/dist/Workspace/File/FileTree/style.js +80 -0
  45. package/dist/Workspace/File/index.d.ts +2 -1
  46. package/dist/Workspace/File/index.js +1 -0
  47. package/dist/Workspace/index.d.ts +4 -2
  48. package/dist/Workspace/index.js +73 -36
  49. package/dist/Workspace/types.d.ts +70 -2
  50. package/package.json +2 -1
@@ -72,14 +72,14 @@ function _unsupported_iterable_to_array(o, minLen) {
72
72
  if (n === "Map" || n === "Set") return Array.from(n);
73
73
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
74
74
  }
75
- import { FileStack, Language, ListTodo, MousePointerClick, X } from "@sofa-design/icons";
75
+ import { FileStack, Language, ListTodo, MousePointerClick, TreeDownArrow, X } from "@sofa-design/icons";
76
76
  import { ConfigProvider, Segmented } from "antd";
77
77
  import classNames from "clsx";
78
78
  import React, { useContext, useEffect, useMemo, useRef, useState } from "react";
79
79
  import { ActionIconBox } from "../Components/ActionIconBox";
80
80
  import { I18nContext } from "../I18n";
81
81
  import Browser from "./Browser";
82
- import { File } from "./File";
82
+ import { File, FileTree } from "./File";
83
83
  import { RealtimeFollowList } from "./RealtimeFollow";
84
84
  import { useWorkspaceStyle } from "./style";
85
85
  import { TaskList } from "./Task";
@@ -88,6 +88,7 @@ var ComponentType = /*#__PURE__*/ function(ComponentType) {
88
88
  ComponentType["BROWSER"] = "browser";
89
89
  ComponentType["TASK"] = "task";
90
90
  ComponentType["FILE"] = "file";
91
+ ComponentType["FILE_TREE"] = "fileTree";
91
92
  ComponentType["CUSTOM"] = "custom";
92
93
  return ComponentType;
93
94
  }(ComponentType || {});
@@ -113,6 +114,11 @@ var DEFAULT_CONFIG = function DEFAULT_CONFIG(locale) {
113
114
  icon: /*#__PURE__*/ React.createElement(FileStack, null),
114
115
  title: (locale === null || locale === void 0 ? void 0 : locale['workspace.file']) || '文件',
115
116
  label: (locale === null || locale === void 0 ? void 0 : locale['workspace.file']) || '文件'
117
+ }), _define_property(_obj, "fileTree", {
118
+ key: "fileTree",
119
+ icon: /*#__PURE__*/ React.createElement(TreeDownArrow, null),
120
+ title: (locale === null || locale === void 0 ? void 0 : locale['workspace.fileTree']) || '文件树',
121
+ label: (locale === null || locale === void 0 ? void 0 : locale['workspace.fileTree']) || '文件树'
116
122
  }), _define_property(_obj, "custom", {
117
123
  key: "custom",
118
124
  icon: null,
@@ -148,6 +154,9 @@ var TaskComponent = function TaskComponent(param) {
148
154
  var FileComponent = function FileComponent(props) {
149
155
  return /*#__PURE__*/ React.createElement(File, props);
150
156
  };
157
+ var FileTreeComponent = function FileTreeComponent(props) {
158
+ return /*#__PURE__*/ React.createElement(FileTree, props);
159
+ };
151
160
  var CustomComponent = function CustomComponent(param) {
152
161
  var children = param.children;
153
162
  return children || null;
@@ -169,6 +178,10 @@ var COMPONENT_MAP = new Map([
169
178
  FileComponent,
170
179
  "file"
171
180
  ],
181
+ [
182
+ FileTreeComponent,
183
+ "fileTree"
184
+ ],
172
185
  [
173
186
  CustomComponent,
174
187
  "custom"
@@ -195,17 +208,36 @@ var COMPONENT_MAP = new Map([
195
208
  locale
196
209
  ]);
197
210
  var _useState2 = _sliced_to_array(useState(''), 2), internalActiveTab = _useState2[0], setInternalActiveTab = _useState2[1];
198
- var availableTabs = useMemo(function() {
199
- var tabs = [];
211
+ var _useMemo = useMemo(function() {
212
+ var _keys_;
213
+ var panelEntries = [];
200
214
  React.Children.forEach(children, function(child, index) {
201
215
  if (!/*#__PURE__*/ React.isValidElement(child)) return;
202
- var componentType = COMPONENT_MAP.get(child.type);
203
- if (!componentType) return;
204
- var tabConfig = resolveTabConfig(child.props.tab, defaultConfig[componentType], componentType === "custom" ? index : undefined);
205
- tabs.push({
206
- key: tabConfig.key,
216
+ var wType = COMPONENT_MAP.get(child.type);
217
+ if (!wType) return;
218
+ var tabConfig = resolveTabConfig(child.props.tab, defaultConfig[wType], wType === "custom" ? index : undefined);
219
+ panelEntries.push({
220
+ wType: wType,
221
+ child: child,
222
+ tabConfig: tabConfig
223
+ });
224
+ });
225
+ var keys = panelEntries.map(function(e) {
226
+ return e.tabConfig.key;
227
+ });
228
+ var isControlled = activeTabKey !== undefined;
229
+ var effectiveKeyForReset = isControlled && activeTabKey !== undefined && activeTabKey !== null && keys.includes(String(activeTabKey)) ? String(activeTabKey) : internalActiveTab && keys.includes(internalActiveTab) ? internalActiveTab : (_keys_ = keys[0]) !== null && _keys_ !== void 0 ? _keys_ : '';
230
+ var firstRealtimeIndex = panelEntries.findIndex(function(e) {
231
+ return e.wType === "realtime";
232
+ });
233
+ var tabs = panelEntries.map(function(entry) {
234
+ var wType = entry.wType, child = entry.child, tabConfig = entry.tabConfig;
235
+ var key = tabConfig.key;
236
+ var shouldPassResetKey = (wType === "file" || wType === "fileTree") && key === effectiveKeyForReset;
237
+ return {
238
+ key: key,
207
239
  icon: tabConfig.icon,
208
- componentType: componentType,
240
+ componentType: wType,
209
241
  label: /*#__PURE__*/ React.createElement("div", {
210
242
  className: classNames("".concat(prefixCls, "-tab-item"), hashId)
211
243
  }, /*#__PURE__*/ React.createElement("span", {
@@ -213,18 +245,41 @@ var COMPONENT_MAP = new Map([
213
245
  }, tabConfig.title), tabConfig.count !== undefined && /*#__PURE__*/ React.createElement("span", {
214
246
  className: classNames("".concat(prefixCls, "-tab-count"), hashId)
215
247
  }, tabConfig.count)),
216
- content: /*#__PURE__*/ React.createElement(child.type, _object_spread({}, child.props, componentType === "file" && {
248
+ content: /*#__PURE__*/ React.createElement(child.type, _object_spread({}, child.props, shouldPassResetKey ? {
217
249
  resetKey: resetKey
218
- }))
219
- });
250
+ } : {}))
251
+ };
220
252
  });
221
- return tabs;
253
+ var options = [];
254
+ for(var i = 0; i < tabs.length; i += 1){
255
+ var tab = tabs[i];
256
+ options.push({
257
+ label: tab.label,
258
+ value: tab.key,
259
+ icon: tab.icon
260
+ });
261
+ var isFirstRealtime = firstRealtimeIndex === i && tab.componentType === "realtime";
262
+ if (isFirstRealtime && tabs.length > 1) {
263
+ options.push({
264
+ label: '',
265
+ value: '__divider__',
266
+ disabled: true
267
+ });
268
+ }
269
+ }
270
+ return {
271
+ availableTabs: tabs,
272
+ segmentedOptions: options
273
+ };
222
274
  }, [
223
275
  children,
224
276
  defaultConfig,
225
277
  hashId,
226
- prefixCls
227
- ]);
278
+ prefixCls,
279
+ resetKey,
280
+ activeTabKey,
281
+ internalActiveTab
282
+ ]), availableTabs = _useMemo.availableTabs, segmentedOptions = _useMemo.segmentedOptions;
228
283
  useEffect(function() {
229
284
  if (!availableTabs.length) return;
230
285
  var isControlled = activeTabKey !== undefined;
@@ -318,26 +373,7 @@ var COMPONENT_MAP = new Map([
318
373
  }, /*#__PURE__*/ React.createElement(Segmented, {
319
374
  key: segmentedKey,
320
375
  className: classNames("".concat(prefixCls, "-segmented"), hashId),
321
- options: availableTabs.reduce(function(acc, param, index) {
322
- var label = param.label, key = param.key, icon = param.icon, componentType = param.componentType;
323
- acc.push({
324
- label: label,
325
- value: key,
326
- icon: icon
327
- });
328
- // 只在第一个"实时跟随"组件后插入分割线
329
- var isFirstRealtime = componentType === "realtime" && availableTabs.findIndex(function(tab) {
330
- return tab.componentType === "realtime";
331
- }) === index;
332
- if (isFirstRealtime && availableTabs.length > 1) {
333
- acc.push({
334
- label: '',
335
- value: '__divider__',
336
- disabled: true
337
- });
338
- }
339
- return acc;
340
- }, []),
376
+ options: segmentedOptions,
341
377
  value: currentActiveTab,
342
378
  onChange: handleTabChange,
343
379
  block: true,
@@ -353,6 +389,7 @@ Workspace.Realtime = RealtimeComponent;
353
389
  Workspace.Browser = BrowserComponent;
354
390
  Workspace.Task = TaskComponent;
355
391
  Workspace.File = FileComponent;
392
+ Workspace.FileTree = FileTreeComponent;
356
393
  Workspace.Custom = CustomComponent;
357
394
  export * from "./File";
358
395
  export default Workspace;
@@ -10,13 +10,18 @@ export interface TabConfiguration {
10
10
  title?: ReactNode;
11
11
  count?: number;
12
12
  }
13
+ /**
14
+ * 工作区内置子面板类型,与 `Workspace.Realtime` / `Workspace.File` 等一一对应
15
+ */
16
+ export type WorkspacePanelType = 'realtime' | 'browser' | 'task' | 'file' | 'fileTree' | 'custom';
13
17
  export interface TabItem {
14
18
  key: string;
15
19
  label: ReactNode;
16
20
  title?: ReactNode;
17
21
  icon?: ReactNode;
18
22
  content?: ReactNode;
19
- componentType?: string;
23
+ /** 子面板类型,用于分割线与内容策略 */
24
+ componentType?: WorkspacePanelType;
20
25
  }
21
26
  export interface WorkspaceProps {
22
27
  activeTabKey?: string;
@@ -168,7 +173,10 @@ export interface FileProps extends BaseChildProps {
168
173
  onToggleGroup?: (groupType: FileType, collapsed: boolean) => void;
169
174
  /** Group 子组件切换事件 */
170
175
  onGroupToggle?: (groupType: FileType, collapsed: boolean) => void;
171
- /** 重置标识,用于重置预览状态(内部使用) */
176
+ /**
177
+ * 重置标识:切换工作区标签时 `Workspace` 会递增,仅在**当前激活**的 `Workspace.File` 上注入,用于关闭预览等;非激活页不接收以避免隐藏面板重复重置
178
+ * @internal
179
+ */
172
180
  resetKey?: number;
173
181
  onPreview?: (file: FileNode) => void | false | FileNode | ReactNode | Promise<void | false | FileNode | ReactNode>;
174
182
  /**
@@ -234,6 +242,66 @@ export interface FileProps extends BaseChildProps {
234
242
  */
235
243
  bindDomId?: boolean;
236
244
  }
245
+ /**
246
+ * 工作区文件树节点(用于 {@link FileTreeProps},与 `antd` Tree 的 `key` 对齐)
247
+ */
248
+ export interface FileTreeNode {
249
+ /** 树节点唯一 key,与 Ant Design Tree 一致 */
250
+ key: string;
251
+ /** 展示名称 */
252
+ name: string;
253
+ /**
254
+ * 是否叶子(文件)节点
255
+ * @description
256
+ * - 懒加载**目录**必须 `isLeaf: false`;若未传 `isLeaf` 且也无 `children` 时视为**文件**(`isLeaf: true`),与「仅省略 `isLeaf` 表示普通文件」一致
257
+ * - 已有子节点时视为目录
258
+ */
259
+ isLeaf?: boolean;
260
+ /** 子节点;懒加载目录为 `isLeaf: false` 时可为 `[]` 或省略,展开后由 `onLoadChildren` 填充,空目录也保持为目录 */
261
+ children?: FileTreeNode[];
262
+ /** 节点图标 */
263
+ icon?: ReactNode;
264
+ /** 是否禁用 */
265
+ disabled?: boolean;
266
+ /** 业务 id,可选,便于与接口字段对应 */
267
+ id?: string;
268
+ }
269
+ /**
270
+ * Workspace 文件树:懒加载目录子项
271
+ */
272
+ export interface FileTreeProps extends BaseChildProps {
273
+ className?: string;
274
+ style?: React.CSSProperties;
275
+ /**
276
+ * 根级树数据
277
+ * @description 子目录可在展开时通过 `onLoadChildren` 拉取并注入
278
+ */
279
+ treeData: FileTreeNode[];
280
+ /**
281
+ * 展开非叶子节点时拉取子节点
282
+ * @param node 当前被展开的节点
283
+ * @returns 子节点列表,可同步或异步
284
+ */
285
+ onLoadChildren: (node: FileTreeNode) => FileTreeNode[] | Promise<FileTreeNode[]>;
286
+ /** 选中节点(点击标题区域)时触发 */
287
+ onSelect?: (node: FileTreeNode) => void;
288
+ /** 是否显示连接线,透传 antd Tree */
289
+ showLine?: boolean;
290
+ /**
291
+ * 由 `Workspace` 在激活项上透传,与 `Workspace.File` 的 `resetKey` 同槽位;不用于清空已懒加载的树状态(树以 `treeData` 为唯一数据源同步)
292
+ * @internal
293
+ */
294
+ resetKey?: number;
295
+ /**
296
+ * 无数据时展示
297
+ * @description 与 File 的 `emptyRender` 行为一致
298
+ */
299
+ emptyRender?: ReactNode | (() => ReactNode);
300
+ /**
301
+ * 是否整行可点选(antd Tree `blockNode`),默认 `true`
302
+ */
303
+ blockNode?: boolean;
304
+ }
237
305
  export interface CustomProps extends BaseChildProps {
238
306
  children?: ReactNode;
239
307
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ant-design/agentic-ui",
3
- "version": "2.30.30",
3
+ "version": "2.30.31",
4
4
  "description": "面向智能体的 UI 组件库,提供多步推理可视化、工具调用展示、任务执行协同等 Agentic UI 能力",
5
5
  "repository": "git@github.com:ant-design/agentic-ui.git",
6
6
  "license": "MIT",
@@ -25,6 +25,7 @@
25
25
  "lint:es": "eslint \"{src,test}/**/*.{js,jsx,ts,tsx}\"",
26
26
  "playwright:install": "playwright install --with-deps chromium",
27
27
  "prepare": "husky install && dumi setup",
28
+ "prepublishOnly": "npm run build",
28
29
  "prettier": "prettier --write \"{src,docs,test}/**/*.{js,jsx,ts,tsx,css,less,json,md}\"",
29
30
  "preview": "pnpm dumi preview",
30
31
  "report:demo": "node scripts/generateDemoReport.js",