@agentscope-ai/flow 0.0.3 → 0.0.5
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/components/custom-inputs-control/index.js +72 -8
- package/dist/components/custom-inputs-control/index.less +0 -2
- package/dist/components/node-result-panel/index.js +5 -5
- package/dist/components/script-code-mirror/index.js +14 -4
- package/dist/types/work-flow.d.ts +2 -2
- package/package.json +1 -1
- package/README.zh-CN.md +0 -67
|
@@ -2,6 +2,8 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
|
|
|
2
2
|
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
3
3
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
4
|
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
5
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
6
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
5
7
|
function _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableRest(); }
|
|
6
8
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
7
9
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
@@ -15,11 +17,11 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
|
|
|
15
17
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
16
18
|
import $i18n from "../../i18n";
|
|
17
19
|
import { extractVariables, matchVariableFromVarItem } from "../../utils";
|
|
18
|
-
import { Button, getCommonConfig, Input, Select } from '@agentscope-ai/design';
|
|
20
|
+
import { Button, Form, getCommonConfig, Input, Select } from '@agentscope-ai/design';
|
|
19
21
|
import { SparkClearLine, SparkDeleteLine, SparkEditLine, SparkPlusLine, SparkQuotationLine } from '@agentscope-ai/icons';
|
|
20
22
|
import { theme, Typography } from 'antd';
|
|
21
23
|
import classNames from 'classnames';
|
|
22
|
-
import React, { memo, useCallback, useMemo } from 'react';
|
|
24
|
+
import React, { memo, useCallback, useEffect, useMemo } from 'react';
|
|
23
25
|
import FlowIcon from "../flow-icon";
|
|
24
26
|
import VariableInput, { VariableBaseInput } from "../variable-input";
|
|
25
27
|
import VariableTreeSelect from "../variable-tree-select";
|
|
@@ -236,11 +238,66 @@ export var VALUE_FROM_OPTIONS = [{
|
|
|
236
238
|
})),
|
|
237
239
|
value: 'input'
|
|
238
240
|
}];
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* 创建变量名验证规则
|
|
244
|
+
* @param allValues 所有变量的值数组,用于检查重复
|
|
245
|
+
* @param currentIndex 当前编辑的变量索引
|
|
246
|
+
*/
|
|
247
|
+
var createVariableNameRules = function createVariableNameRules(allValues, currentIndex) {
|
|
248
|
+
return [{
|
|
249
|
+
validator: function validator(_, value) {
|
|
250
|
+
if (!value || value.trim() === '') {
|
|
251
|
+
return Promise.resolve();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// 检查是否以数字开头
|
|
255
|
+
if (/^\d/.test(value)) {
|
|
256
|
+
return Promise.reject(new Error($i18n.get({
|
|
257
|
+
id: 'spark-flow.components.CustomInputsControl.index.variableNameCannotStartWithNumber',
|
|
258
|
+
dm: '变量名不能以数字开头'
|
|
259
|
+
})));
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// 检查是否包含非法字符
|
|
263
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(value)) {
|
|
264
|
+
return Promise.reject(new Error($i18n.get({
|
|
265
|
+
id: 'spark-flow.components.CustomInputsControl.index.variableNameOnlyAllowLettersNumbersUnderscores',
|
|
266
|
+
dm: '变量名只能包含字母、数字和下划线'
|
|
267
|
+
})));
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// 检查是否重复
|
|
271
|
+
var isDuplicate = allValues.some(function (item, index) {
|
|
272
|
+
return index !== currentIndex && item.key === value && item.key !== '';
|
|
273
|
+
});
|
|
274
|
+
if (isDuplicate) {
|
|
275
|
+
return Promise.reject(new Error($i18n.get({
|
|
276
|
+
id: 'spark-flow.components.CustomInputsControl.index.variableNameDuplicate',
|
|
277
|
+
dm: '变量名不能重复'
|
|
278
|
+
})));
|
|
279
|
+
}
|
|
280
|
+
return Promise.resolve();
|
|
281
|
+
}
|
|
282
|
+
}];
|
|
283
|
+
};
|
|
239
284
|
export default /*#__PURE__*/memo(function CustomInputsControl(props) {
|
|
240
285
|
var _props$value = props.value,
|
|
241
286
|
value = _props$value === void 0 ? [] : _props$value;
|
|
242
287
|
var _theme$useToken = theme.useToken(),
|
|
243
288
|
token = _theme$useToken.token;
|
|
289
|
+
var _Form$useForm = Form.useForm(),
|
|
290
|
+
_Form$useForm2 = _slicedToArray(_Form$useForm, 1),
|
|
291
|
+
form = _Form$useForm2[0];
|
|
292
|
+
|
|
293
|
+
// 同步 value 到 form
|
|
294
|
+
useEffect(function () {
|
|
295
|
+
var formValues = {};
|
|
296
|
+
value.forEach(function (item, index) {
|
|
297
|
+
formValues["var_".concat(index)] = item.key;
|
|
298
|
+
});
|
|
299
|
+
form.setFieldsValue(formValues);
|
|
300
|
+
}, [value, form]);
|
|
244
301
|
var changeRowValue = useCallback(function (ind, payload) {
|
|
245
302
|
var newVal = value.map(function (item, index) {
|
|
246
303
|
if (index === ind) {
|
|
@@ -267,7 +324,10 @@ export default /*#__PURE__*/memo(function CustomInputsControl(props) {
|
|
|
267
324
|
}, [props.onChange, value]);
|
|
268
325
|
var _getCommonConfig = getCommonConfig(),
|
|
269
326
|
antPrefix = _getCommonConfig.antPrefix;
|
|
270
|
-
return /*#__PURE__*/React.createElement(
|
|
327
|
+
return /*#__PURE__*/React.createElement(Form, {
|
|
328
|
+
form: form,
|
|
329
|
+
component: false
|
|
330
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
271
331
|
className: "spark-flow-inputs-form-label flex gap-[8px]"
|
|
272
332
|
}, /*#__PURE__*/React.createElement("div", {
|
|
273
333
|
style: {
|
|
@@ -290,12 +350,16 @@ export default /*#__PURE__*/memo(function CustomInputsControl(props) {
|
|
|
290
350
|
return /*#__PURE__*/React.createElement("div", {
|
|
291
351
|
key: index,
|
|
292
352
|
className: "spark-flow-inputs-form-item flex gap-[8px] items-stretch w-full"
|
|
293
|
-
}, /*#__PURE__*/React.createElement(
|
|
353
|
+
}, /*#__PURE__*/React.createElement(Form.Item, {
|
|
354
|
+
name: "var_".concat(index),
|
|
294
355
|
style: {
|
|
295
|
-
width: props.disabledValueFrom ? 146 : 84
|
|
356
|
+
width: props.disabledValueFrom ? 146 : 84,
|
|
357
|
+
marginBottom: 0,
|
|
358
|
+
flexShrink: 0
|
|
296
359
|
},
|
|
297
|
-
|
|
298
|
-
|
|
360
|
+
validateTrigger: ['onChange', 'onBlur'],
|
|
361
|
+
rules: createVariableNameRules(value, index)
|
|
362
|
+
}, /*#__PURE__*/React.createElement(Input, {
|
|
299
363
|
placeholder: $i18n.get({
|
|
300
364
|
id: 'spark-flow.components.CustomInputsControl.index.enterVariableName',
|
|
301
365
|
dm: '请输入变量名'
|
|
@@ -312,7 +376,7 @@ export default /*#__PURE__*/memo(function CustomInputsControl(props) {
|
|
|
312
376
|
color: token.colorError
|
|
313
377
|
}
|
|
314
378
|
}, "*") : null
|
|
315
|
-
}), !props.disabledValueFrom && /*#__PURE__*/React.createElement(Select, {
|
|
379
|
+
})), !props.disabledValueFrom && /*#__PURE__*/React.createElement(Select, {
|
|
316
380
|
style: {
|
|
317
381
|
width: 60
|
|
318
382
|
},
|
|
@@ -74,27 +74,27 @@ var NodeResultPanel = function NodeResultPanel(props) {
|
|
|
74
74
|
_useState2 = _slicedToArray(_useState, 2),
|
|
75
75
|
expand = _useState2[0],
|
|
76
76
|
setExpand = _useState2[1];
|
|
77
|
-
var
|
|
77
|
+
var batch = props.data.batch && !!props.data.batches;
|
|
78
78
|
var _useState3 = useState(1),
|
|
79
79
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
80
80
|
batchIndex = _useState4[0],
|
|
81
81
|
setBatchIndex = _useState4[1];
|
|
82
82
|
var inputContent = useMemo(function () {
|
|
83
|
-
if (
|
|
83
|
+
if (batch) {
|
|
84
84
|
var _props$data$batches;
|
|
85
85
|
return (_props$data$batches = props.data.batches[batchIndex - 1]) === null || _props$data$batches === void 0 ? void 0 : _props$data$batches.input;
|
|
86
86
|
}
|
|
87
87
|
return props.data.input;
|
|
88
88
|
}, [props.data, batchIndex]);
|
|
89
89
|
var outputContent = useMemo(function () {
|
|
90
|
-
if (
|
|
90
|
+
if (batch) {
|
|
91
91
|
var _props$data$batches2;
|
|
92
92
|
return (_props$data$batches2 = props.data.batches[batchIndex - 1]) === null || _props$data$batches2 === void 0 ? void 0 : _props$data$batches2.output;
|
|
93
93
|
}
|
|
94
94
|
return props.data.output;
|
|
95
95
|
}, [props.data, batchIndex]);
|
|
96
96
|
var errorInfoContent = useMemo(function () {
|
|
97
|
-
if (
|
|
97
|
+
if (batch) {
|
|
98
98
|
var _props$data$batches3;
|
|
99
99
|
return (_props$data$batches3 = props.data.batches[batchIndex - 1]) === null || _props$data$batches3 === void 0 ? void 0 : _props$data$batches3.errorInfo;
|
|
100
100
|
}
|
|
@@ -123,7 +123,7 @@ var NodeResultPanel = function NodeResultPanel(props) {
|
|
|
123
123
|
className: "spark-flow-node-result-time"
|
|
124
124
|
}, props.data.nodeExecTime)), props.data.nodeStatus !== 'skip' && /*#__PURE__*/React.createElement(SparkUpLine, {
|
|
125
125
|
className: "text-base spark-flow-node-result-expand-icon"
|
|
126
|
-
})), expand &&
|
|
126
|
+
})), expand && batch && /*#__PURE__*/React.createElement(Pagination, {
|
|
127
127
|
current: batchIndex,
|
|
128
128
|
total: props.data.batches.length,
|
|
129
129
|
pageSize: 1,
|
|
@@ -62,10 +62,6 @@ var createCompletionSource = function createCompletionSource(inputParams) {
|
|
|
62
62
|
console.log('IME composing, blocking autocomplete');
|
|
63
63
|
return null;
|
|
64
64
|
}
|
|
65
|
-
|
|
66
|
-
// 恢复原来的匹配逻辑:匹配任意单词字符
|
|
67
|
-
var word = context.matchBefore(/\w*/);
|
|
68
|
-
if (!word) return null;
|
|
69
65
|
var completions = _toConsumableArray(inputParams.map(function (param) {
|
|
70
66
|
return {
|
|
71
67
|
label: "params.".concat(param.key),
|
|
@@ -73,6 +69,20 @@ var createCompletionSource = function createCompletionSource(inputParams) {
|
|
|
73
69
|
info: "Params parameter: ".concat(param.key, " (").concat(param.type, ")")
|
|
74
70
|
};
|
|
75
71
|
}));
|
|
72
|
+
|
|
73
|
+
// 检查是否是 / 触发的补全
|
|
74
|
+
var slashMatch = context.matchBefore(/\/\w*/);
|
|
75
|
+
if (slashMatch) {
|
|
76
|
+
return {
|
|
77
|
+
from: slashMatch.from + 1,
|
|
78
|
+
// 从 / 后面开始替换,保留 /
|
|
79
|
+
options: completions
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 正常的单词补全:使用 \w+ 确保至少有一个字符,避免特殊字符触发
|
|
84
|
+
var word = context.matchBefore(/\w+/);
|
|
85
|
+
if (!word) return null;
|
|
76
86
|
return {
|
|
77
87
|
from: word.from,
|
|
78
88
|
options: completions
|
|
@@ -120,7 +120,7 @@ export interface IWorkFlowTaskResultItem {
|
|
|
120
120
|
parentNodeId?: string;
|
|
121
121
|
}
|
|
122
122
|
export interface IWorkFlowNodeResultItem {
|
|
123
|
-
|
|
123
|
+
batch: boolean;
|
|
124
124
|
retry?: {
|
|
125
125
|
happened: boolean;
|
|
126
126
|
retryTimes: number;
|
|
@@ -133,7 +133,7 @@ export interface IWorkFlowNodeResultItem {
|
|
|
133
133
|
totalTokens: number;
|
|
134
134
|
}[];
|
|
135
135
|
batches: IWorkFlowNodeResultItem[];
|
|
136
|
-
|
|
136
|
+
multiBranch: boolean;
|
|
137
137
|
multiBranchResults?: {
|
|
138
138
|
conditionId: string;
|
|
139
139
|
targetIds: string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentscope-ai/flow",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "A powerful and flexible flow canvas rendering engine designed for AI applications. Provides comprehensive workflow visualization and interaction capabilities for platforms like Bailian and AgentScope, enabling seamless creation and management of complex AI agent workflows with an intuitive drag-and-drop interface.",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
package/README.zh-CN.md
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# Spark Flow
|
|
2
|
-
## 项目介绍
|
|
3
|
-
Spark Flow是供给主包`packages/main`的画布编辑基础业务组件,主要技术栈包含React、React Flow、Antd、zustand等。
|
|
4
|
-
|
|
5
|
-
### 主要功能
|
|
6
|
-
+ 节点检查清单列表;
|
|
7
|
-
+ 节点管理器;
|
|
8
|
-
+ 画布执行状态管理;
|
|
9
|
-
+ 支持回退、撤销;
|
|
10
|
-
+ 支持全生命周期快速定制业务节点;
|
|
11
|
-
+ 支持复杂节点交互;
|
|
12
|
-
|
|
13
|
-
### 项目主要结构
|
|
14
|
-
```plain
|
|
15
|
-
spark-flow/
|
|
16
|
-
├── docs/
|
|
17
|
-
├── public/ # 静态资源文件
|
|
18
|
-
├── src/
|
|
19
|
-
│ ├── components/ # 基础组件
|
|
20
|
-
│ ├── constant/ # 可视化工作流编辑器
|
|
21
|
-
│ ├── demos/ # 国际化支持
|
|
22
|
-
│ ├── flow/ # 画布组件主入口
|
|
23
|
-
│ ├── hooks/ # 画布类操作工具库
|
|
24
|
-
│ ├── i18n/ # 国际化
|
|
25
|
-
│ ├── store/ # 全局状态管理
|
|
26
|
-
│ ├── types/ # 类型定义
|
|
27
|
-
| ├── utils/ # 函数工具库
|
|
28
|
-
| ├── index.less/ # less变量定义
|
|
29
|
-
| └── index.ts/ # 项目主入口文件
|
|
30
|
-
└── package.json # 项目配置
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
#### 节点结构
|
|
34
|
-
```plain
|
|
35
|
-
[业务节点名]
|
|
36
|
-
├── node # 画布节点渲染
|
|
37
|
-
├── panel # 节点配置面板
|
|
38
|
-
└── schema # 节点Schema协议配置
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
#### 自定义
|
|
42
|
-
+ 通过覆盖 `packages/spark-flow/src/index.less` 中的 `@ant-prefix` 可以修改样式文件中的自定义类名和 CSS 变量名前缀;
|
|
43
|
-
+ 同时需要在项目中通过 `ConfigProvider` 设置自定义类名和 CSS 变量名前缀:
|
|
44
|
-
```
|
|
45
|
-
import { ConfigProvider } from '@agentscope-ai/design';
|
|
46
|
-
|
|
47
|
-
<ConfigProvider prefix="efm" prefixCls="efm_ant>
|
|
48
|
-
...
|
|
49
|
-
</ConfigProvider>
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## 如何开发
|
|
53
|
-
### 快速启动
|
|
54
|
-
```shell
|
|
55
|
-
npm run re-install && cd packages/spark-flow && npm start
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
+ **安装依赖** 在根目录执行`npm run re-install`
|
|
59
|
-
+ **运行** cd`packages/spark-flow`且执行`npm start`
|
|
60
|
-
|
|
61
|
-
### 开发
|
|
62
|
-
> [!NOTE]
|
|
63
|
-
> **注意:** 前提是你完成了快速启动的 **安装依赖** 操作
|
|
64
|
-
|
|
65
|
-
+ 开发完之后根目录下执行`npm run fresh:flow`能够快速清除主包`packages/main`的依赖;
|
|
66
|
-
+ 进入主包`packages/main`执行`npm start`
|
|
67
|
-
+ 进行测试 & 验证;
|