Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 35 additions & 45 deletions ui/src/workflow-canvas/config/node-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,6 @@ export const parameterExtractionNode = {
properties: { stepName: '参数提取', config: { fields: [{ label: '结果', value: 'result' }] } },
}


/* 知识库检索 */
export const searchKnowledgeNode = {
type: WorkflowNodeType.SearchKnowledge,
Expand Down Expand Up @@ -344,7 +343,6 @@ export const rerankerNode = {
},
}


/* MCP 调用 */
export const mcpNode = {
type: WorkflowNodeType.McpNode,
Expand All @@ -361,7 +359,6 @@ export const toolCustomNode = {
properties: { stepName: '自定义工具', config: { fields: [{ label: '结果', value: 'result' }] } },
}


/* 智能体节点 */
export const applicationNode = {
type: WorkflowNodeType.Application,
Expand All @@ -370,99 +367,92 @@ export const applicationNode = {
properties: { stepName: '智能体节点', config: { fields: [{ label: '结果', value: 'result' }] } },
}


/**
* 工具配置数据
*/
export const toolLibNode = {
type: WorkflowNodeType.ToolLib,
text: '通过执行自定义脚本,实现数据处理',
label: '自定义工具',
height: 170,
properties: { stepName: '自定义工具', config: { fields: [{ label: '结果', value: 'result' }] } },
}

/**
* 工作流工具配置数据
*/
export const toolWorkflowLibNode = {
type: WorkflowNodeType.ToolWorkflowLib,
text: '工作流工具',
label: '工作流工具',
height: 170,
properties: { stepName: '工作流工具', config: { fields: [] } },
text: '工具节点',
label: '工具节点',
properties: { stepName: '工具节点', config: { fields: [{ label: '结果', value: 'result' }] } },
}




export const loopStartNode = {
id: WorkflowNodeType.LoopStartNode,
type: WorkflowNodeType.LoopStartNode,
x: 480,
y: 3340,
properties: {
height: 364,
stepName: '循环开始',
config: {
fields: [
{ label: '下标', value: 'index' },
{ label: '循环元素', value: 'item' },
],
globalFields: [],
},
showNode: true,
},
}
/* 循环节点 */

export const loopNode = {
type: WorkflowNodeType.LoopNode,
visible: false,
text: '通过设置循环次数和逻辑,重复执行一系列任务',
label: '循环节点',
height: 252,
properties: {
stepName: '循环节点',
workflow: {
edges: [],
nodes: [
{
x: 480,
y: 3340,
y: 200,
id: 'loop-start-node',
type: 'loop-start-node',
properties: { config: { fields: [], globalFields: [] }, fields: [], height: 361.333, showNode: true, stepName: '开始', globalFields: [] },
properties: { config: { fields: [], globalFields: [] }, fields: [], showNode: true, stepName: '开始', globalFields: [] },
},
],
},
config: { fields: [] },
},
}

export const loopStartNode = {
id: WorkflowNodeType.LoopStartNode,
type: WorkflowNodeType.LoopStartNode,
x: 480,
y: 200,
properties: {
stepName: '循环开始',
config: {
fields: [
{ label: '下标', value: 'index' },
{ label: '循环元素', value: 'item' },
],
globalFields: [],
},
showNode: true,
},
}

export const loopBodyNode = {
type: WorkflowNodeType.LoopBodyNode,
text: '循环体',
label: '循环体',
height: 1080,

properties: { width: 1920, stepName: '循环体', config: { fields: [] } },
}

export const loopContinueNode = {
type: WorkflowNodeType.LoopContinueNode,
text: '用于终止当前循环,执行下次循环',
label: 'Continue',
height: 100,
properties: { width: 600, stepName: 'Continue', config: { fields: [] } },
}

export const loopBreakNode = {
type: WorkflowNodeType.LoopBreakNode,
text: '终止当前循环,跳出循环体',
label: 'Break',
height: 100,
properties: { width: 600, stepName: 'Break', config: { fields: [] } },
}

/**
* 工作流工具配置数据
*/
export const toolWorkflowLibNode = {
type: WorkflowNodeType.ToolWorkflowLib,
text: '工作流工具',
label: '工作流工具',
properties: { stepName: '工作流工具', config: { fields: [] } },
}

/* 文档分段 */
export const documentSplitNode = {
type: WorkflowNodeType.DocumentSplitNode,
Expand Down
8 changes: 4 additions & 4 deletions ui/src/workflow-canvas/core/node-container/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -273,16 +273,16 @@ onBeforeUnmount(() => {
>
<div>
<div class="flex-between">
<div class="flex items-center" @dragstart.prevent @drag.prevent @dragover.prevent @dragend.prevent>
<component :is="iconComponent(`${model.type}-icon`)" class="mr-2" :size="24" :item="model?.properties.node_data" />
<div class="flex min-w-0 flex-1 items-center" @dragstart.prevent @drag.prevent @dragover.prevent @dragend.prevent>
<component :is="iconComponent(`${model.type}-icon`)" class="mr-2 shrink-0" :size="24" :item="model?.properties.node_data" />
<h4
class="truncate break-all"
class="truncate"
:title="String(model.properties.stepName ?? '')"
v-html="highlightedStepName(String(model.properties.stepName ?? ''))"
></h4>
</div>

<div class="flex items-center gap-1" @pointerdown.stop @mousemove.stop @mousedown.stop @keydown.stop @click.stop>
<div class="flex shrink-0 items-center gap-1" @pointerdown.stop @mousemove.stop @mousedown.stop @keydown.stop @click.stop>
<el-button text @click="showNode = !showNode">
<MkIcon name="icon_down_outlined" />
</el-button>
Expand Down
23 changes: 23 additions & 0 deletions ui/src/workflow-canvas/icons/tool-lib-node-icon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script setup lang="ts">
import type { ToolType } from '@/api/types'

const props = defineProps<{
item?: {
name: string
icon: string
tool_type: ToolType
kind?: string
}
size?: string | number
}>()
</script>

<template>
<ToolIcon v-if="item?.kind !== 'data-source'" :icon="props.item?.icon" :type="props.item?.tool_type" />
<el-avatar v-else-if="item?.kind === 'data-source'" class="bg-purple!" shape="square">
<img src="@/assets/tool/icon_datasource.svg" style="width: 58%" alt="" />
</el-avatar>
<el-avatar v-else class="bg-success!" shape="square" :size="size">
<img style="width: 63%" src="@/assets/tool/icon_tool.svg" alt="" />
</el-avatar>
</template>
2 changes: 1 addition & 1 deletion ui/src/workflow-canvas/nodes/loop-body-node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class LoopBodyModel extends WorkflowNodeModel {
loopLayout?: () => void

getDefaultAnchor(): Model.AnchorConfig[] {
return [{ x: this.x, y: this.y - this.height / 2 + 10, id: `${this.id}_children`, type: 'children', edgeAddable: false }]
return [{ x: this.x, y: this.y - this.height / 2, id: `${this.id}_children`, type: 'children', edgeAddable: false }]
}

refreshBranch() {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/workflow-canvas/nodes/loop-node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Model } from '@logicflow/core'
class LoopNodeModel extends WorkflowNodeModel {
getDefaultAnchor(): Model.AnchorConfig[] {
const anchors = super.getDefaultAnchor()
anchors.push({ x: this.x, y: this.y + this.height / 2 - 25, id: `${this.id}_children`, type: 'children', edgeAddable: false })
anchors.push({ x: this.x, y: this.y + this.height / 2, id: `${this.id}_children`, type: 'children', edgeAddable: false })
return anchors
}

Expand Down
2 changes: 1 addition & 1 deletion ui/src/workflow-canvas/nodes/loop-node/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function mountLoopBodyNode() {
edges: [],
}
let x = model.x
let y = model.y + 350
let y = model.y + 850
if (nodeData?.loop_body) workflow = nodeData.loop_body
if (nodeData?.loop) {
x = nodeData.loop.x
Expand Down
52 changes: 27 additions & 25 deletions ui/src/workflow-canvas/nodes/tool-lib-node/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,36 +104,38 @@ onMounted(() => {

<div class="mk-gray-card">
<el-form ref="formRef" :model="formData" label-position="top" hide-required-asterisk @submit.prevent>
<!-- 输入参数 -->
<h6 class="mb-2">输入参数</h6>
<template v-if="formData.input_field_list.length">
<el-form-item
v-for="(field, index) in formData.input_field_list"
:key="`${field.name}-${index}`"
:prop="`input_field_list.${index}.value`"
:rules="{
required: field.is_required,
message: field.source === 'reference' ? '请选择参数' : '请输入参数',
trigger: field.source === 'reference' ? 'change' : 'blur',
}"
>
<template #label>
<div class="flex w-full items-center gap-1">
<span class="max-w-40 truncate" :class="{ 'mk-required': field.is_required }" :title="field.name">{{ field.name }}</span>
<el-tooltip v-if="field.desc" :content="field.desc" effect="dark" placement="right">
<MkIcon name="icon_info_outlined" class="text-N600!" />
</el-tooltip>
<el-tag size="small" type="info">{{ field.type }}</el-tag>
</div>
</template>

<NodeCascader v-if="field.source === 'reference'" v-model="field.value" :node-model="model" placeholder="请选择参数" />
<el-input v-else v-model="field.value" placeholder="请输入参数" />
</el-form-item>
<div class="mk-white-card">
<el-form-item
v-for="(field, index) in formData.input_field_list"
:key="`${field.name}-${index}`"
:prop="`input_field_list.${index}.value`"
:rules="{
required: field.is_required,
message: field.source === 'reference' ? '请选择参数' : '请输入参数',
trigger: field.source === 'reference' ? 'change' : 'blur',
}"
>
<template #label>
<div class="flex w-full items-center gap-1">
<span class="max-w-40 truncate" :class="{ 'mk-required': field.is_required }" :title="field.name">{{ field.name }}</span>
<el-tooltip v-if="field.desc" :content="field.desc" effect="dark" placement="right">
<MkIcon name="icon_info_outlined" class="text-N600!" />
</el-tooltip>
<el-tag size="small" type="info">{{ field.type }}</el-tag>
</div>
</template>

<NodeCascader v-if="field.source === 'reference'" v-model="field.value" :node-model="model" placeholder="请选择参数" />
<el-input v-else v-model="field.value" placeholder="请输入参数" />
</el-form-item>
</div>
</template>
<MkEmpty v-else :image-size="60" class="mb-4" />

<!-- 返回内容 -->
<div v-if="showReturnContent" class="flex-between w-full">
<div v-if="showReturnContent" class="flex-between w-full mt-4">
<span class="flex items-center gap-1">
返回内容
<el-tooltip content="关闭后该节点的内容则不输出给用户。如果你想让用户看到该节点的输出内容,请打开开关。" placement="right">
Expand Down
Loading