diff --git a/ui/src/enums/application.ts b/ui/src/enums/application.ts
index 173a723e064..7a667ffaa79 100644
--- a/ui/src/enums/application.ts
+++ b/ui/src/enums/application.ts
@@ -14,6 +14,7 @@ export enum WorkflowType {
Question = 'question-node',
Condition = 'condition-node',
Reply = 'reply-node',
+ EmptyNode = 'empty-node',
ToolLib = 'tool-lib-node',
ToolWorkflowLib = 'tool-workflow-lib-node',
ToolLibCustom = 'tool-node',
diff --git a/ui/src/locales/lang/en-US/workflow.ts b/ui/src/locales/lang/en-US/workflow.ts
index f322667c8a3..39eb526a755 100644
--- a/ui/src/locales/lang/en-US/workflow.ts
+++ b/ui/src/locales/lang/en-US/workflow.ts
@@ -243,6 +243,12 @@ You are a master of problem optimization, adept at accurately inferring user int
text: 'Specify reply content, referenced variables will be converted to strings for output',
replyContent: 'Reply Content',
},
+ emptyNode: {
+ label: 'Empty Node',
+ text: 'No operation, used as a placeholder node in the workflow',
+ description: 'This is an empty node',
+ hint: 'Used when no action is needed',
+ },
rerankerNode: {
label: 'Multi-path Recall',
text: 'Use a re-ranking model to refine retrieval results from multiple knowledge sources',
diff --git a/ui/src/locales/lang/zh-CN/workflow.ts b/ui/src/locales/lang/zh-CN/workflow.ts
index 42cdf5a89f7..8708a39896f 100644
--- a/ui/src/locales/lang/zh-CN/workflow.ts
+++ b/ui/src/locales/lang/zh-CN/workflow.ts
@@ -243,6 +243,12 @@ export default {
text: '指定回复内容,引用变量会转换为字符串进行输出',
replyContent: '回复内容',
},
+ emptyNode: {
+ label: '空节点',
+ text: '不执行任何操作,仅作为流程占位节点使用',
+ description: '这是一个空节点',
+ hint: '当不需要执行任何操作时使用',
+ },
rerankerNode: {
label: '多路召回',
text: '使用重排模型对多个知识库的检索结果进行二次召回',
diff --git a/ui/src/locales/lang/zh-Hant/views/application.ts b/ui/src/locales/lang/zh-Hant/views/application.ts
index 988d0958593..4c2406c1687 100644
--- a/ui/src/locales/lang/zh-Hant/views/application.ts
+++ b/ui/src/locales/lang/zh-Hant/views/application.ts
@@ -129,7 +129,7 @@ export default {
},
reasoningContent: {
label: '輸出思考',
- tooltip: '請根據模型返回的思考標簽設置,標簽中間的內容將會認定爲思考過程',
+ tooltip: '請根據模型返回的思考標籤設置,標籤中間的內容將會認定爲思考過程',
start: '開始',
end: '結束',
},
diff --git a/ui/src/locales/lang/zh-Hant/workflow.ts b/ui/src/locales/lang/zh-Hant/workflow.ts
index 6678d4536a7..e3b32abd64f 100644
--- a/ui/src/locales/lang/zh-Hant/workflow.ts
+++ b/ui/src/locales/lang/zh-Hant/workflow.ts
@@ -194,7 +194,7 @@ export default {
custom: '手動',
customTooltip: '手動設置標籤過濾條件',
auto: '自動',
- autoTooltip: '根據檢索問題自動匹配文檔標簽',
+ autoTooltip: '根據檢索問題自動匹配文檔標籤',
documentList: '文檔列表',
knowledgeList: '知識庫列表',
result: '檢索結果',
@@ -243,6 +243,12 @@ export default {
text: '指定回覆內容,引用變量會轉換為字符串進行輸出',
replyContent: '回覆內容',
},
+ emptyNode: {
+ label: '空節點',
+ text: '不執行任何操作,僅作爲流程佔位節點使用',
+ description: '這是一個空節點',
+ hint: '當不需要執行任何操作時使用',
+ },
rerankerNode: {
label: '多路召回',
text: '使用重排模型對多個知識庫的檢索結果進行二次召回',
diff --git a/ui/src/workflow/common/NodeContainer.vue b/ui/src/workflow/common/NodeContainer.vue
index 162a678ff41..35619e2a498 100644
--- a/ui/src/workflow/common/NodeContainer.vue
+++ b/ui/src/workflow/common/NodeContainer.vue
@@ -13,7 +13,6 @@
@drag.prevent
@dragover.prevent
@dragend.prevent
- style="width: 69%"
>
-
+
diff --git a/ui/src/workflow/common/data.ts b/ui/src/workflow/common/data.ts
index 23fe80e60e2..b184a4a2e22 100644
--- a/ui/src/workflow/common/data.ts
+++ b/ui/src/workflow/common/data.ts
@@ -356,6 +356,18 @@ export const replyNode = {
},
},
}
+export const emptyNode = {
+ type: WorkflowType.EmptyNode,
+ text: t('workflow.nodes.emptyNode.text'),
+ label: t('workflow.nodes.emptyNode.label'),
+ height: 150,
+ properties: {
+ stepName: t('workflow.nodes.emptyNode.label'),
+ config: {
+ fields: [],
+ },
+ },
+}
export const rerankerNode = {
type: WorkflowType.RerankerNode,
text: t('workflow.nodes.rerankerNode.text'),
@@ -784,7 +796,6 @@ export const knowledgeMenuNodes = [
questionNode,
],
},
-
{
label: t('workflow.nodes.classify.businessLogic'),
list: [conditionNode, replyNode, loopNode],
@@ -800,7 +811,7 @@ export const knowledgeMenuNodes = [
},
{
label: t('common.other'),
- list: [mcpNode, toolNode],
+ list: [mcpNode, toolNode, emptyNode],
},
]
@@ -839,7 +850,7 @@ export const menuNodes = [
},
{
label: t('common.other'),
- list: [mcpNode, toolNode],
+ list: [mcpNode, toolNode, emptyNode],
},
]
export const applicationLoopMenuNodes = [
@@ -877,7 +888,7 @@ export const applicationLoopMenuNodes = [
},
{
label: t('common.other'),
- list: [mcpNode, toolNode],
+ list: [mcpNode, toolNode, emptyNode],
},
]
export const knowledgeLoopMenuNodes = [
@@ -919,7 +930,7 @@ export const knowledgeLoopMenuNodes = [
},
{
label: t('common.other'),
- list: [mcpNode, toolNode],
+ list: [mcpNode, toolNode, emptyNode],
},
]
export const toolLoopMenuNodes = [
@@ -961,7 +972,7 @@ export const toolLoopMenuNodes = [
},
{
label: t('common.other'),
- list: [mcpNode, toolNode],
+ list: [mcpNode, toolNode, emptyNode],
},
]
const toolMenuNodes = [
@@ -1005,7 +1016,7 @@ const toolMenuNodes = [
},
{
label: t('common.other'),
- list: [mcpNode, toolNode],
+ list: [mcpNode, toolNode, emptyNode],
},
]
export const getMenuNodes = (workflowMode: WorkflowMode) => {
@@ -1152,6 +1163,7 @@ export const nodeDict: any = {
[WorkflowType.Base]: baseNode,
[WorkflowType.Start]: startNode,
[WorkflowType.Reply]: replyNode,
+ [WorkflowType.EmptyNode]: emptyNode,
[WorkflowType.ToolLib]: toolNode,
[WorkflowType.ToolWorkflowLib]: toolWorkflowLibNode,
[WorkflowType.ToolLibCustom]: toolNode,
@@ -1283,6 +1295,7 @@ const nodeLocaleBindings: Array<[any, string, string]> = [
],
[conditionNode, 'workflow.nodes.conditionNode.text', 'workflow.nodes.conditionNode.label'],
[replyNode, 'workflow.nodes.replyNode.text', 'workflow.nodes.replyNode.label'],
+ [emptyNode, 'workflow.nodes.emptyNode.text', 'workflow.nodes.emptyNode.label'],
[rerankerNode, 'workflow.nodes.rerankerNode.text', 'workflow.nodes.rerankerNode.label'],
[formNode, 'workflow.nodes.formNode.text', 'workflow.nodes.formNode.label'],
[
diff --git a/ui/src/workflow/common/validate.ts b/ui/src/workflow/common/validate.ts
index 08c7f8935d8..5e5c0d48377 100644
--- a/ui/src/workflow/common/validate.ts
+++ b/ui/src/workflow/common/validate.ts
@@ -6,6 +6,7 @@ import { t } from '@/locales'
const end_nodes: Array = [
WorkflowType.AiChat,
WorkflowType.Reply,
+ WorkflowType.EmptyNode,
WorkflowType.ToolLib,
WorkflowType.ToolLibCustom,
WorkflowType.ImageUnderstandNode,
@@ -27,6 +28,7 @@ const end_nodes: Array = [
const loop_end_nodes: Array = [
WorkflowType.AiChat,
WorkflowType.Reply,
+ WorkflowType.EmptyNode,
WorkflowType.ToolLib,
WorkflowType.ToolLibCustom,
WorkflowType.ImageUnderstandNode,
diff --git a/ui/src/workflow/icons/empty-node-icon.vue b/ui/src/workflow/icons/empty-node-icon.vue
new file mode 100644
index 00000000000..70b25f259df
--- /dev/null
+++ b/ui/src/workflow/icons/empty-node-icon.vue
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/ui/src/workflow/nodes/empty-node/index.ts b/ui/src/workflow/nodes/empty-node/index.ts
new file mode 100644
index 00000000000..1a415e9f899
--- /dev/null
+++ b/ui/src/workflow/nodes/empty-node/index.ts
@@ -0,0 +1,14 @@
+import EmptyNodeVue from './index.vue'
+import { AppNode, AppNodeModel } from '@/workflow/common/app-node'
+
+class EmptyNode extends AppNode {
+ constructor(props: any) {
+ super(props, EmptyNodeVue)
+ }
+}
+
+export default {
+ type: 'empty-node',
+ model: AppNodeModel,
+ view: EmptyNode
+}
diff --git a/ui/src/workflow/nodes/empty-node/index.vue b/ui/src/workflow/nodes/empty-node/index.vue
new file mode 100644
index 00000000000..b6292a26dab
--- /dev/null
+++ b/ui/src/workflow/nodes/empty-node/index.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
{{ $t('workflow.nodes.emptyNode.description') }}
+
{{ $t('workflow.nodes.emptyNode.hint') }}
+
+
+
+
+
+
+
+