balibabu
commited on
Commit
·
79cd49c
1
Parent(s):
6fd4084
feat: Add component Invoke #2908 (#3067)
Browse files### What problem does this PR solve?
feat: Add component Invoke #2908
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- web/package-lock.json +36 -0
- web/package.json +1 -0
- web/src/assets/svg/invoke-ai.svg +15 -0
- web/src/locales/en.ts +8 -0
- web/src/locales/zh-traditional.ts +8 -0
- web/src/locales/zh.ts +8 -0
- web/src/pages/flow/constant.tsx +22 -0
- web/src/pages/flow/flow-drawer/index.tsx +4 -0
- web/src/pages/flow/form/invoke-form/dynamic-variables.tsx +119 -0
- web/src/pages/flow/form/invoke-form/hooks.ts +87 -0
- web/src/pages/flow/form/invoke-form/index.less +21 -0
- web/src/pages/flow/form/invoke-form/index.tsx +72 -0
- web/src/pages/flow/hooks.ts +2 -0
- web/src/pages/flow/interface.ts +4 -0
web/package-lock.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
| 11 |
"@ant-design/pro-layout": "^7.17.16",
|
| 12 |
"@antv/g6": "^5.0.10",
|
| 13 |
"@js-preview/excel": "^1.7.8",
|
|
|
|
| 14 |
"@tanstack/react-query": "^5.40.0",
|
| 15 |
"@tanstack/react-query-devtools": "^5.51.5",
|
| 16 |
"ahooks": "^3.7.10",
|
|
@@ -3843,6 +3844,30 @@
|
|
| 3843 |
"resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz",
|
| 3844 |
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
| 3845 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3846 |
"node_modules/@mrmlnc/readdir-enhanced": {
|
| 3847 |
"version": "2.2.1",
|
| 3848 |
"resolved": "https://registry.npmmirror.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
|
@@ -19956,6 +19981,12 @@
|
|
| 19956 |
"node": "*"
|
| 19957 |
}
|
| 19958 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19959 |
"node_modules/mri": {
|
| 19960 |
"version": "1.2.0",
|
| 19961 |
"resolved": "https://registry.npmmirror.com/mri/-/mri-1.2.0.tgz",
|
|
@@ -25827,6 +25858,11 @@
|
|
| 25827 |
"resolved": "https://registry.npmmirror.com/stackframe/-/stackframe-1.3.4.tgz",
|
| 25828 |
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="
|
| 25829 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25830 |
"node_modules/static-extend": {
|
| 25831 |
"version": "0.1.2",
|
| 25832 |
"resolved": "https://registry.npmmirror.com/static-extend/-/static-extend-0.1.2.tgz",
|
|
|
|
| 11 |
"@ant-design/pro-layout": "^7.17.16",
|
| 12 |
"@antv/g6": "^5.0.10",
|
| 13 |
"@js-preview/excel": "^1.7.8",
|
| 14 |
+
"@monaco-editor/react": "^4.6.0",
|
| 15 |
"@tanstack/react-query": "^5.40.0",
|
| 16 |
"@tanstack/react-query-devtools": "^5.51.5",
|
| 17 |
"ahooks": "^3.7.10",
|
|
|
|
| 3844 |
"resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz",
|
| 3845 |
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
| 3846 |
},
|
| 3847 |
+
"node_modules/@monaco-editor/loader": {
|
| 3848 |
+
"version": "1.4.0",
|
| 3849 |
+
"resolved": "https://registry.npmmirror.com/@monaco-editor/loader/-/loader-1.4.0.tgz",
|
| 3850 |
+
"integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==",
|
| 3851 |
+
"dependencies": {
|
| 3852 |
+
"state-local": "^1.0.6"
|
| 3853 |
+
},
|
| 3854 |
+
"peerDependencies": {
|
| 3855 |
+
"monaco-editor": ">= 0.21.0 < 1"
|
| 3856 |
+
}
|
| 3857 |
+
},
|
| 3858 |
+
"node_modules/@monaco-editor/react": {
|
| 3859 |
+
"version": "4.6.0",
|
| 3860 |
+
"resolved": "https://registry.npmmirror.com/@monaco-editor/react/-/react-4.6.0.tgz",
|
| 3861 |
+
"integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==",
|
| 3862 |
+
"dependencies": {
|
| 3863 |
+
"@monaco-editor/loader": "^1.4.0"
|
| 3864 |
+
},
|
| 3865 |
+
"peerDependencies": {
|
| 3866 |
+
"monaco-editor": ">= 0.25.0 < 1",
|
| 3867 |
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
| 3868 |
+
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
| 3869 |
+
}
|
| 3870 |
+
},
|
| 3871 |
"node_modules/@mrmlnc/readdir-enhanced": {
|
| 3872 |
"version": "2.2.1",
|
| 3873 |
"resolved": "https://registry.npmmirror.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
|
|
|
| 19981 |
"node": "*"
|
| 19982 |
}
|
| 19983 |
},
|
| 19984 |
+
"node_modules/monaco-editor": {
|
| 19985 |
+
"version": "0.52.0",
|
| 19986 |
+
"resolved": "https://registry.npmmirror.com/monaco-editor/-/monaco-editor-0.52.0.tgz",
|
| 19987 |
+
"integrity": "sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==",
|
| 19988 |
+
"peer": true
|
| 19989 |
+
},
|
| 19990 |
"node_modules/mri": {
|
| 19991 |
"version": "1.2.0",
|
| 19992 |
"resolved": "https://registry.npmmirror.com/mri/-/mri-1.2.0.tgz",
|
|
|
|
| 25858 |
"resolved": "https://registry.npmmirror.com/stackframe/-/stackframe-1.3.4.tgz",
|
| 25859 |
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="
|
| 25860 |
},
|
| 25861 |
+
"node_modules/state-local": {
|
| 25862 |
+
"version": "1.0.7",
|
| 25863 |
+
"resolved": "https://registry.npmmirror.com/state-local/-/state-local-1.0.7.tgz",
|
| 25864 |
+
"integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="
|
| 25865 |
+
},
|
| 25866 |
"node_modules/static-extend": {
|
| 25867 |
"version": "0.1.2",
|
| 25868 |
"resolved": "https://registry.npmmirror.com/static-extend/-/static-extend-0.1.2.tgz",
|
web/package.json
CHANGED
|
@@ -22,6 +22,7 @@
|
|
| 22 |
"@ant-design/pro-layout": "^7.17.16",
|
| 23 |
"@antv/g6": "^5.0.10",
|
| 24 |
"@js-preview/excel": "^1.7.8",
|
|
|
|
| 25 |
"@tanstack/react-query": "^5.40.0",
|
| 26 |
"@tanstack/react-query-devtools": "^5.51.5",
|
| 27 |
"ahooks": "^3.7.10",
|
|
|
|
| 22 |
"@ant-design/pro-layout": "^7.17.16",
|
| 23 |
"@antv/g6": "^5.0.10",
|
| 24 |
"@js-preview/excel": "^1.7.8",
|
| 25 |
+
"@monaco-editor/react": "^4.6.0",
|
| 26 |
"@tanstack/react-query": "^5.40.0",
|
| 27 |
"@tanstack/react-query-devtools": "^5.51.5",
|
| 28 |
"ahooks": "^3.7.10",
|
web/src/assets/svg/invoke-ai.svg
ADDED
|
|
web/src/locales/en.ts
CHANGED
|
@@ -29,6 +29,7 @@ export default {
|
|
| 29 |
move: 'Move',
|
| 30 |
warn: 'Warn',
|
| 31 |
action: 'Action',
|
|
|
|
| 32 |
},
|
| 33 |
login: {
|
| 34 |
login: 'Sign in',
|
|
@@ -1016,6 +1017,13 @@ The above is the content you need to summarize.`,
|
|
| 1016 |
note: 'Note',
|
| 1017 |
noteDescription: 'Note',
|
| 1018 |
notePlaceholder: 'Please enter a note',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1019 |
},
|
| 1020 |
footer: {
|
| 1021 |
profile: 'All rights reserved @ React',
|
|
|
|
| 29 |
move: 'Move',
|
| 30 |
warn: 'Warn',
|
| 31 |
action: 'Action',
|
| 32 |
+
s: 'S',
|
| 33 |
},
|
| 34 |
login: {
|
| 35 |
login: 'Sign in',
|
|
|
|
| 1017 |
note: 'Note',
|
| 1018 |
noteDescription: 'Note',
|
| 1019 |
notePlaceholder: 'Please enter a note',
|
| 1020 |
+
invoke: 'Invoke',
|
| 1021 |
+
invokeDescription:
|
| 1022 |
+
'This component can invoke remote end point call. Put the output of other components as parameters or set constant parameters to call remote functions.',
|
| 1023 |
+
url: 'Url',
|
| 1024 |
+
method: 'Method',
|
| 1025 |
+
timeout: 'Timeout',
|
| 1026 |
+
headers: 'Headers',
|
| 1027 |
},
|
| 1028 |
footer: {
|
| 1029 |
profile: 'All rights reserved @ React',
|
web/src/locales/zh-traditional.ts
CHANGED
|
@@ -29,6 +29,7 @@ export default {
|
|
| 29 |
move: '移動',
|
| 30 |
warn: '提醒',
|
| 31 |
action: '操作',
|
|
|
|
| 32 |
},
|
| 33 |
login: {
|
| 34 |
login: '登入',
|
|
@@ -965,6 +966,13 @@ export default {
|
|
| 965 |
note: '註解',
|
| 966 |
noteDescription: '註解',
|
| 967 |
notePlaceholder: '請輸入註釋',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 968 |
},
|
| 969 |
footer: {
|
| 970 |
profile: '“保留所有權利 @ react”',
|
|
|
|
| 29 |
move: '移動',
|
| 30 |
warn: '提醒',
|
| 31 |
action: '操作',
|
| 32 |
+
s: '秒',
|
| 33 |
},
|
| 34 |
login: {
|
| 35 |
login: '登入',
|
|
|
|
| 966 |
note: '註解',
|
| 967 |
noteDescription: '註解',
|
| 968 |
notePlaceholder: '請輸入註釋',
|
| 969 |
+
invoke: 'Invoke',
|
| 970 |
+
invokeDescription:
|
| 971 |
+
'此元件可以呼叫遠端端點呼叫。將其他元件的輸出作為參數或設定常數參數來呼叫遠端函數。',
|
| 972 |
+
url: '網址',
|
| 973 |
+
method: '方法',
|
| 974 |
+
timeout: '超時',
|
| 975 |
+
headers: '請求頭',
|
| 976 |
},
|
| 977 |
footer: {
|
| 978 |
profile: '“保留所有權利 @ react”',
|
web/src/locales/zh.ts
CHANGED
|
@@ -29,6 +29,7 @@ export default {
|
|
| 29 |
move: '移动',
|
| 30 |
warn: '提醒',
|
| 31 |
action: '操作',
|
|
|
|
| 32 |
},
|
| 33 |
login: {
|
| 34 |
login: '登录',
|
|
@@ -985,6 +986,13 @@ export default {
|
|
| 985 |
note: '注释',
|
| 986 |
noteDescription: '注释',
|
| 987 |
notePlaceholder: '请输入注释',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 988 |
},
|
| 989 |
footer: {
|
| 990 |
profile: 'All rights reserved @ React',
|
|
|
|
| 29 |
move: '移动',
|
| 30 |
warn: '提醒',
|
| 31 |
action: '操作',
|
| 32 |
+
s: '秒',
|
| 33 |
},
|
| 34 |
login: {
|
| 35 |
login: '登录',
|
|
|
|
| 986 |
note: '注释',
|
| 987 |
noteDescription: '注释',
|
| 988 |
notePlaceholder: '请输入注释',
|
| 989 |
+
invoke: 'Invoke',
|
| 990 |
+
invokeDescription:
|
| 991 |
+
'该组件可以调用远程端点调用。将其他组件的输出作为参数或设置常量参数来调用远程函数。',
|
| 992 |
+
url: 'Url',
|
| 993 |
+
method: '方法',
|
| 994 |
+
timeout: '超时',
|
| 995 |
+
headers: '请求头',
|
| 996 |
},
|
| 997 |
footer: {
|
| 998 |
profile: 'All rights reserved @ React',
|
web/src/pages/flow/constant.tsx
CHANGED
|
@@ -12,6 +12,7 @@ import { ReactComponent as ExeSqlIcon } from '@/assets/svg/exesql.svg';
|
|
| 12 |
import { ReactComponent as GithubIcon } from '@/assets/svg/github.svg';
|
| 13 |
import { ReactComponent as GoogleScholarIcon } from '@/assets/svg/google-scholar.svg';
|
| 14 |
import { ReactComponent as GoogleIcon } from '@/assets/svg/google.svg';
|
|
|
|
| 15 |
import { ReactComponent as Jin10Icon } from '@/assets/svg/jin10.svg';
|
| 16 |
import { ReactComponent as KeywordIcon } from '@/assets/svg/keyword.svg';
|
| 17 |
import { ReactComponent as NoteIcon } from '@/assets/svg/note.svg';
|
|
@@ -75,6 +76,7 @@ export enum Operator {
|
|
| 75 |
TuShare = 'TuShare',
|
| 76 |
Note = 'Note',
|
| 77 |
Crawler = 'Crawler',
|
|
|
|
| 78 |
}
|
| 79 |
|
| 80 |
export const CommonOperatorList = Object.values(Operator).filter(
|
|
@@ -113,6 +115,7 @@ export const operatorIconMap = {
|
|
| 113 |
[Operator.TuShare]: TuShareIcon,
|
| 114 |
[Operator.Note]: NoteIcon,
|
| 115 |
[Operator.Crawler]: CrawlerIcon,
|
|
|
|
| 116 |
};
|
| 117 |
|
| 118 |
export const operatorMap: Record<
|
|
@@ -239,6 +242,9 @@ export const operatorMap: Record<
|
|
| 239 |
[Operator.Crawler]: {
|
| 240 |
backgroundColor: '#dee0e2',
|
| 241 |
},
|
|
|
|
|
|
|
|
|
|
| 242 |
};
|
| 243 |
|
| 244 |
export const componentMenuList = [
|
|
@@ -332,6 +338,9 @@ export const componentMenuList = [
|
|
| 332 |
{
|
| 333 |
name: Operator.Crawler,
|
| 334 |
},
|
|
|
|
|
|
|
|
|
|
| 335 |
];
|
| 336 |
|
| 337 |
export const initialRetrievalValues = {
|
|
@@ -509,6 +518,18 @@ export const initialCrawlerValues = {
|
|
| 509 |
extract_type: 'markdown',
|
| 510 |
};
|
| 511 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 512 |
export const CategorizeAnchorPointPositions = [
|
| 513 |
{ top: 1, right: 34 },
|
| 514 |
{ top: 8, right: 18 },
|
|
@@ -621,6 +642,7 @@ export const NodeMap = {
|
|
| 621 |
[Operator.TuShare]: 'ragNode',
|
| 622 |
[Operator.Note]: 'noteNode',
|
| 623 |
[Operator.Crawler]: 'ragNode',
|
|
|
|
| 624 |
};
|
| 625 |
|
| 626 |
export const LanguageOptions = [
|
|
|
|
| 12 |
import { ReactComponent as GithubIcon } from '@/assets/svg/github.svg';
|
| 13 |
import { ReactComponent as GoogleScholarIcon } from '@/assets/svg/google-scholar.svg';
|
| 14 |
import { ReactComponent as GoogleIcon } from '@/assets/svg/google.svg';
|
| 15 |
+
import { ReactComponent as InvokeIcon } from '@/assets/svg/invoke-ai.svg';
|
| 16 |
import { ReactComponent as Jin10Icon } from '@/assets/svg/jin10.svg';
|
| 17 |
import { ReactComponent as KeywordIcon } from '@/assets/svg/keyword.svg';
|
| 18 |
import { ReactComponent as NoteIcon } from '@/assets/svg/note.svg';
|
|
|
|
| 76 |
TuShare = 'TuShare',
|
| 77 |
Note = 'Note',
|
| 78 |
Crawler = 'Crawler',
|
| 79 |
+
Invoke = 'Invoke',
|
| 80 |
}
|
| 81 |
|
| 82 |
export const CommonOperatorList = Object.values(Operator).filter(
|
|
|
|
| 115 |
[Operator.TuShare]: TuShareIcon,
|
| 116 |
[Operator.Note]: NoteIcon,
|
| 117 |
[Operator.Crawler]: CrawlerIcon,
|
| 118 |
+
[Operator.Invoke]: InvokeIcon,
|
| 119 |
};
|
| 120 |
|
| 121 |
export const operatorMap: Record<
|
|
|
|
| 242 |
[Operator.Crawler]: {
|
| 243 |
backgroundColor: '#dee0e2',
|
| 244 |
},
|
| 245 |
+
[Operator.Invoke]: {
|
| 246 |
+
backgroundColor: '#dee0e2',
|
| 247 |
+
},
|
| 248 |
};
|
| 249 |
|
| 250 |
export const componentMenuList = [
|
|
|
|
| 338 |
{
|
| 339 |
name: Operator.Crawler,
|
| 340 |
},
|
| 341 |
+
{
|
| 342 |
+
name: Operator.Invoke,
|
| 343 |
+
},
|
| 344 |
];
|
| 345 |
|
| 346 |
export const initialRetrievalValues = {
|
|
|
|
| 518 |
extract_type: 'markdown',
|
| 519 |
};
|
| 520 |
|
| 521 |
+
export const initialInvokeValues = {
|
| 522 |
+
url: 'http://',
|
| 523 |
+
method: 'GET',
|
| 524 |
+
timeout: 60,
|
| 525 |
+
headers: `{
|
| 526 |
+
"Accept": "*/*",
|
| 527 |
+
"Cache-Control": "no-cache",
|
| 528 |
+
"Connection": "keep-alive"
|
| 529 |
+
}`,
|
| 530 |
+
proxy: 'http://',
|
| 531 |
+
};
|
| 532 |
+
|
| 533 |
export const CategorizeAnchorPointPositions = [
|
| 534 |
{ top: 1, right: 34 },
|
| 535 |
{ top: 8, right: 18 },
|
|
|
|
| 642 |
[Operator.TuShare]: 'ragNode',
|
| 643 |
[Operator.Note]: 'noteNode',
|
| 644 |
[Operator.Crawler]: 'ragNode',
|
| 645 |
+
[Operator.Invoke]: 'ragNode',
|
| 646 |
};
|
| 647 |
|
| 648 |
export const LanguageOptions = [
|
web/src/pages/flow/flow-drawer/index.tsx
CHANGED
|
@@ -20,6 +20,7 @@ import GenerateForm from '../form/generate-form';
|
|
| 20 |
import GithubForm from '../form/github-form';
|
| 21 |
import GoogleForm from '../form/google-form';
|
| 22 |
import GoogleScholarForm from '../form/google-scholar-form';
|
|
|
|
| 23 |
import Jin10Form from '../form/jin10-form';
|
| 24 |
import KeywordExtractForm from '../form/keyword-extract-form';
|
| 25 |
import MessageForm from '../form/message-form';
|
|
@@ -74,6 +75,9 @@ const FormMap = {
|
|
| 74 |
[Operator.Jin10]: Jin10Form,
|
| 75 |
[Operator.TuShare]: TuShareForm,
|
| 76 |
[Operator.Crawler]: CrawlerForm,
|
|
|
|
|
|
|
|
|
|
| 77 |
};
|
| 78 |
|
| 79 |
const EmptyContent = () => <div></div>;
|
|
|
|
| 20 |
import GithubForm from '../form/github-form';
|
| 21 |
import GoogleForm from '../form/google-form';
|
| 22 |
import GoogleScholarForm from '../form/google-scholar-form';
|
| 23 |
+
import InvokeForm from '../form/invoke-form';
|
| 24 |
import Jin10Form from '../form/jin10-form';
|
| 25 |
import KeywordExtractForm from '../form/keyword-extract-form';
|
| 26 |
import MessageForm from '../form/message-form';
|
|
|
|
| 75 |
[Operator.Jin10]: Jin10Form,
|
| 76 |
[Operator.TuShare]: TuShareForm,
|
| 77 |
[Operator.Crawler]: CrawlerForm,
|
| 78 |
+
[Operator.Invoke]: InvokeForm,
|
| 79 |
+
[Operator.Concentrator]: <></>,
|
| 80 |
+
[Operator.Note]: <></>,
|
| 81 |
};
|
| 82 |
|
| 83 |
const EmptyContent = () => <div></div>;
|
web/src/pages/flow/form/invoke-form/dynamic-variables.tsx
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { EditableCell, EditableRow } from '@/components/editable-cell';
|
| 2 |
+
import { useTranslate } from '@/hooks/common-hooks';
|
| 3 |
+
import { DeleteOutlined } from '@ant-design/icons';
|
| 4 |
+
import { Button, Flex, Input, Select, Table, TableProps } from 'antd';
|
| 5 |
+
import { useBuildComponentIdSelectOptions } from '../../hooks';
|
| 6 |
+
import { IInvokeVariable } from '../../interface';
|
| 7 |
+
import { useHandleOperateParameters } from './hooks';
|
| 8 |
+
|
| 9 |
+
import { trim } from 'lodash';
|
| 10 |
+
import styles from './index.less';
|
| 11 |
+
|
| 12 |
+
interface IProps {
|
| 13 |
+
nodeId?: string;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
const components = {
|
| 17 |
+
body: {
|
| 18 |
+
row: EditableRow,
|
| 19 |
+
cell: EditableCell,
|
| 20 |
+
},
|
| 21 |
+
};
|
| 22 |
+
|
| 23 |
+
const DynamicVariables = ({ nodeId }: IProps) => {
|
| 24 |
+
const { t } = useTranslate('flow');
|
| 25 |
+
|
| 26 |
+
const options = useBuildComponentIdSelectOptions(nodeId);
|
| 27 |
+
const {
|
| 28 |
+
dataSource,
|
| 29 |
+
handleAdd,
|
| 30 |
+
handleRemove,
|
| 31 |
+
handleSave,
|
| 32 |
+
handleComponentIdChange,
|
| 33 |
+
handleValueChange,
|
| 34 |
+
} = useHandleOperateParameters(nodeId!);
|
| 35 |
+
|
| 36 |
+
const columns: TableProps<IInvokeVariable>['columns'] = [
|
| 37 |
+
{
|
| 38 |
+
title: t('key'),
|
| 39 |
+
dataIndex: 'key',
|
| 40 |
+
key: 'key',
|
| 41 |
+
// width: 40,
|
| 42 |
+
onCell: (record: IInvokeVariable) => ({
|
| 43 |
+
record,
|
| 44 |
+
editable: true,
|
| 45 |
+
dataIndex: 'key',
|
| 46 |
+
title: 'key',
|
| 47 |
+
handleSave,
|
| 48 |
+
}),
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
title: t('componentId'),
|
| 52 |
+
dataIndex: 'component_id',
|
| 53 |
+
key: 'component_id',
|
| 54 |
+
align: 'center',
|
| 55 |
+
width: 140,
|
| 56 |
+
render(text, record) {
|
| 57 |
+
return (
|
| 58 |
+
<Select
|
| 59 |
+
style={{ width: '100%' }}
|
| 60 |
+
allowClear
|
| 61 |
+
options={options}
|
| 62 |
+
value={text}
|
| 63 |
+
disabled={trim(record.value) !== ''}
|
| 64 |
+
onChange={handleComponentIdChange(record)}
|
| 65 |
+
/>
|
| 66 |
+
);
|
| 67 |
+
},
|
| 68 |
+
},
|
| 69 |
+
{
|
| 70 |
+
title: t('value'),
|
| 71 |
+
dataIndex: 'value',
|
| 72 |
+
key: 'value',
|
| 73 |
+
align: 'center',
|
| 74 |
+
width: 140,
|
| 75 |
+
render(text, record) {
|
| 76 |
+
return (
|
| 77 |
+
<Input
|
| 78 |
+
value={text}
|
| 79 |
+
disabled={!!record.component_id}
|
| 80 |
+
onChange={handleValueChange(record)}
|
| 81 |
+
/>
|
| 82 |
+
);
|
| 83 |
+
},
|
| 84 |
+
},
|
| 85 |
+
{
|
| 86 |
+
title: t('operation'),
|
| 87 |
+
dataIndex: 'operation',
|
| 88 |
+
width: 20,
|
| 89 |
+
key: 'operation',
|
| 90 |
+
align: 'center',
|
| 91 |
+
fixed: 'right',
|
| 92 |
+
render(_, record) {
|
| 93 |
+
return <DeleteOutlined onClick={handleRemove(record.id)} />;
|
| 94 |
+
},
|
| 95 |
+
},
|
| 96 |
+
];
|
| 97 |
+
|
| 98 |
+
return (
|
| 99 |
+
<section>
|
| 100 |
+
<Flex justify="end">
|
| 101 |
+
<Button size="small" onClick={handleAdd}>
|
| 102 |
+
{t('add')}
|
| 103 |
+
</Button>
|
| 104 |
+
</Flex>
|
| 105 |
+
<Table
|
| 106 |
+
dataSource={dataSource}
|
| 107 |
+
columns={columns}
|
| 108 |
+
rowKey={'id'}
|
| 109 |
+
className={styles.variableTable}
|
| 110 |
+
components={components}
|
| 111 |
+
rowClassName={() => styles.editableRow}
|
| 112 |
+
scroll={{ x: true }}
|
| 113 |
+
bordered
|
| 114 |
+
/>
|
| 115 |
+
</section>
|
| 116 |
+
);
|
| 117 |
+
};
|
| 118 |
+
|
| 119 |
+
export default DynamicVariables;
|
web/src/pages/flow/form/invoke-form/hooks.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import get from 'lodash/get';
|
| 2 |
+
import { ChangeEventHandler, useCallback, useMemo } from 'react';
|
| 3 |
+
import { v4 as uuid } from 'uuid';
|
| 4 |
+
import { IGenerateParameter, IInvokeVariable } from '../../interface';
|
| 5 |
+
import useGraphStore from '../../store';
|
| 6 |
+
|
| 7 |
+
export const useHandleOperateParameters = (nodeId: string) => {
|
| 8 |
+
const { getNode, updateNodeForm } = useGraphStore((state) => state);
|
| 9 |
+
const node = getNode(nodeId);
|
| 10 |
+
const dataSource: IGenerateParameter[] = useMemo(
|
| 11 |
+
() => get(node, 'data.form.variables', []) as IGenerateParameter[],
|
| 12 |
+
[node],
|
| 13 |
+
);
|
| 14 |
+
|
| 15 |
+
const changeValue = useCallback(
|
| 16 |
+
(row: IInvokeVariable, field: string, value: string) => {
|
| 17 |
+
const newData = [...dataSource];
|
| 18 |
+
const index = newData.findIndex((item) => row.id === item.id);
|
| 19 |
+
const item = newData[index];
|
| 20 |
+
newData.splice(index, 1, {
|
| 21 |
+
...item,
|
| 22 |
+
[field]: value,
|
| 23 |
+
});
|
| 24 |
+
|
| 25 |
+
updateNodeForm(nodeId, { variables: newData });
|
| 26 |
+
},
|
| 27 |
+
[dataSource, nodeId, updateNodeForm],
|
| 28 |
+
);
|
| 29 |
+
|
| 30 |
+
const handleComponentIdChange = useCallback(
|
| 31 |
+
(row: IInvokeVariable) => (value: string) => {
|
| 32 |
+
changeValue(row, 'component_id', value);
|
| 33 |
+
},
|
| 34 |
+
[changeValue],
|
| 35 |
+
);
|
| 36 |
+
|
| 37 |
+
const handleValueChange = useCallback(
|
| 38 |
+
(row: IInvokeVariable): ChangeEventHandler<HTMLInputElement> =>
|
| 39 |
+
(e) => {
|
| 40 |
+
changeValue(row, 'value', e.target.value);
|
| 41 |
+
},
|
| 42 |
+
[changeValue],
|
| 43 |
+
);
|
| 44 |
+
|
| 45 |
+
const handleRemove = useCallback(
|
| 46 |
+
(id?: string) => () => {
|
| 47 |
+
const newData = dataSource.filter((item) => item.id !== id);
|
| 48 |
+
updateNodeForm(nodeId, { variables: newData });
|
| 49 |
+
},
|
| 50 |
+
[updateNodeForm, nodeId, dataSource],
|
| 51 |
+
);
|
| 52 |
+
|
| 53 |
+
const handleAdd = useCallback(() => {
|
| 54 |
+
updateNodeForm(nodeId, {
|
| 55 |
+
variables: [
|
| 56 |
+
...dataSource,
|
| 57 |
+
{
|
| 58 |
+
id: uuid(),
|
| 59 |
+
key: '',
|
| 60 |
+
component_id: undefined,
|
| 61 |
+
value: '',
|
| 62 |
+
},
|
| 63 |
+
],
|
| 64 |
+
});
|
| 65 |
+
}, [dataSource, nodeId, updateNodeForm]);
|
| 66 |
+
|
| 67 |
+
const handleSave = (row: IGenerateParameter) => {
|
| 68 |
+
const newData = [...dataSource];
|
| 69 |
+
const index = newData.findIndex((item) => row.id === item.id);
|
| 70 |
+
const item = newData[index];
|
| 71 |
+
newData.splice(index, 1, {
|
| 72 |
+
...item,
|
| 73 |
+
...row,
|
| 74 |
+
});
|
| 75 |
+
|
| 76 |
+
updateNodeForm(nodeId, { variables: newData });
|
| 77 |
+
};
|
| 78 |
+
|
| 79 |
+
return {
|
| 80 |
+
handleAdd,
|
| 81 |
+
handleRemove,
|
| 82 |
+
handleComponentIdChange,
|
| 83 |
+
handleValueChange,
|
| 84 |
+
handleSave,
|
| 85 |
+
dataSource,
|
| 86 |
+
};
|
| 87 |
+
};
|
web/src/pages/flow/form/invoke-form/index.less
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.variableTable {
|
| 2 |
+
margin-top: 14px;
|
| 3 |
+
}
|
| 4 |
+
.editableRow {
|
| 5 |
+
:global(.editable-cell) {
|
| 6 |
+
position: relative;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
:global(.editable-cell-value-wrap) {
|
| 10 |
+
padding: 5px 12px;
|
| 11 |
+
cursor: pointer;
|
| 12 |
+
height: 30px !important;
|
| 13 |
+
}
|
| 14 |
+
&:hover {
|
| 15 |
+
:global(.editable-cell-value-wrap) {
|
| 16 |
+
padding: 4px 11px;
|
| 17 |
+
border: 1px solid #d9d9d9;
|
| 18 |
+
border-radius: 2px;
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
}
|
web/src/pages/flow/form/invoke-form/index.tsx
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import Editor from '@monaco-editor/react';
|
| 2 |
+
import { Form, Input, InputNumber, Select, Space } from 'antd';
|
| 3 |
+
import { useTranslation } from 'react-i18next';
|
| 4 |
+
import { useSetLlmSetting } from '../../hooks';
|
| 5 |
+
import { IOperatorForm } from '../../interface';
|
| 6 |
+
import DynamicVariables from './dynamic-variables';
|
| 7 |
+
|
| 8 |
+
enum Method {
|
| 9 |
+
GET = 'GET',
|
| 10 |
+
POST = 'POST',
|
| 11 |
+
PUT = 'PUT',
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
const MethodOptions = [Method.GET, Method.POST, Method.PUT].map((x) => ({
|
| 15 |
+
label: x,
|
| 16 |
+
value: x,
|
| 17 |
+
}));
|
| 18 |
+
|
| 19 |
+
interface TimeoutInputProps {
|
| 20 |
+
value?: number;
|
| 21 |
+
onChange?: (value: number | null) => void;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
const TimeoutInput = ({ value, onChange }: TimeoutInputProps) => {
|
| 25 |
+
const { t } = useTranslation();
|
| 26 |
+
return (
|
| 27 |
+
<Space>
|
| 28 |
+
<InputNumber value={value} onChange={onChange} /> {t('common.s')}
|
| 29 |
+
</Space>
|
| 30 |
+
);
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
const InvokeForm = ({ onValuesChange, form, node }: IOperatorForm) => {
|
| 34 |
+
const { t } = useTranslation();
|
| 35 |
+
|
| 36 |
+
useSetLlmSetting(form);
|
| 37 |
+
|
| 38 |
+
return (
|
| 39 |
+
<>
|
| 40 |
+
<Form
|
| 41 |
+
name="basic"
|
| 42 |
+
autoComplete="off"
|
| 43 |
+
form={form}
|
| 44 |
+
onValuesChange={onValuesChange}
|
| 45 |
+
layout={'vertical'}
|
| 46 |
+
>
|
| 47 |
+
<Form.Item name={'url'} label={t('flow.url')}>
|
| 48 |
+
<Input />
|
| 49 |
+
</Form.Item>
|
| 50 |
+
<Form.Item
|
| 51 |
+
name={'method'}
|
| 52 |
+
label={t('flow.method')}
|
| 53 |
+
initialValue={Method.GET}
|
| 54 |
+
>
|
| 55 |
+
<Select options={MethodOptions} />
|
| 56 |
+
</Form.Item>
|
| 57 |
+
<Form.Item name={'timeout'} label={t('flow.timeout')}>
|
| 58 |
+
<TimeoutInput></TimeoutInput>
|
| 59 |
+
</Form.Item>
|
| 60 |
+
<Form.Item name={'headers'} label={t('flow.headers')}>
|
| 61 |
+
<Editor height={200} defaultLanguage="json" theme="vs-dark" />
|
| 62 |
+
</Form.Item>
|
| 63 |
+
<Form.Item name={'proxy'} label={t('flow.proxy')}>
|
| 64 |
+
<Input />
|
| 65 |
+
</Form.Item>
|
| 66 |
+
<DynamicVariables nodeId={node?.id}></DynamicVariables>
|
| 67 |
+
</Form>
|
| 68 |
+
</>
|
| 69 |
+
);
|
| 70 |
+
};
|
| 71 |
+
|
| 72 |
+
export default InvokeForm;
|
web/src/pages/flow/hooks.ts
CHANGED
|
@@ -49,6 +49,7 @@ import {
|
|
| 49 |
initialGithubValues,
|
| 50 |
initialGoogleScholarValues,
|
| 51 |
initialGoogleValues,
|
|
|
|
| 52 |
initialJin10Values,
|
| 53 |
initialKeywordExtractValues,
|
| 54 |
initialMessageValues,
|
|
@@ -132,6 +133,7 @@ export const useInitializeOperatorParams = () => {
|
|
| 132 |
[Operator.TuShare]: initialTuShareValues,
|
| 133 |
[Operator.Note]: initialNoteValues,
|
| 134 |
[Operator.Crawler]: initialCrawlerValues,
|
|
|
|
| 135 |
};
|
| 136 |
}, [llmId]);
|
| 137 |
|
|
|
|
| 49 |
initialGithubValues,
|
| 50 |
initialGoogleScholarValues,
|
| 51 |
initialGoogleValues,
|
| 52 |
+
initialInvokeValues,
|
| 53 |
initialJin10Values,
|
| 54 |
initialKeywordExtractValues,
|
| 55 |
initialMessageValues,
|
|
|
|
| 133 |
[Operator.TuShare]: initialTuShareValues,
|
| 134 |
[Operator.Note]: initialNoteValues,
|
| 135 |
[Operator.Crawler]: initialCrawlerValues,
|
| 136 |
+
[Operator.Invoke]: initialInvokeValues,
|
| 137 |
};
|
| 138 |
}, [llmId]);
|
| 139 |
|
web/src/pages/flow/interface.ts
CHANGED
|
@@ -51,6 +51,10 @@ export interface IGenerateParameter {
|
|
| 51 |
component_id?: string;
|
| 52 |
}
|
| 53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
export type ICategorizeItemResult = Record<
|
| 55 |
string,
|
| 56 |
Omit<ICategorizeItem, 'name'>
|
|
|
|
| 51 |
component_id?: string;
|
| 52 |
}
|
| 53 |
|
| 54 |
+
export interface IInvokeVariable extends IGenerateParameter {
|
| 55 |
+
value?: string;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
export type ICategorizeItemResult = Record<
|
| 59 |
string,
|
| 60 |
Omit<ICategorizeItem, 'name'>
|