feat: Variable aggregation

This commit is contained in:
zhangzhanwei 2025-10-17 17:29:12 +08:00 committed by zhanweizhang7
parent 3e1e434dbf
commit 4b0dd1b7c0
13 changed files with 84 additions and 4 deletions

View File

@ -14,7 +14,7 @@ from (select application."id"::text, application."name",
application.icon
from application
left join "user" on user_id = "user".id
where application."id" in (select target
where application."id"::text in (select target
from workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
and 'VIEW' = any (permission_list))) temp
${application_query_set}

View File

@ -308,4 +308,4 @@ class FolderTreeSerializer(serializers.Serializer):
TreeSerializer = get_folder_tree_serializer(self.data.get('source')) # noqa
serializer = TreeSerializer(nodes, many=True)
return serializer.data # 这是可序列化的字典
return [d for d in serializer.data if d.get('id') == d.get('workspace_id')] # 这是可序列化的字典

View File

@ -22,7 +22,7 @@ FROM (SELECT "temp_knowledge".id::text, "temp_knowledge".name,
"document_temp".document_count
FROM (SELECT knowledge.*
FROM knowledge knowledge ${knowledge_custom_sql}
AND id in (select target
AND id::text in (select target
from workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
and 'VIEW' = any (permission_list))) temp_knowledge
LEFT JOIN (SELECT "count"("id") AS document_count, "sum"("char_length") "char_length", knowledge_id

View File

@ -20,7 +20,7 @@ FROM (SELECT tool."id"::text,
tool."is_active"
FROM (SELECT tool.*
FROM tool tool ${tool_query_set}
AND tool.id IN (SELECT target
AND tool.id::text IN (SELECT target
FROM workspace_user_resource_permission
${workspace_user_resource_permission_query_set}
AND 'VIEW' = ANY (permission_list))) AS tool

View File

@ -0,0 +1,12 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5696_2019)">
<path d="M0 12C0 6.34315 0 3.51472 1.75736 1.75736C3.51472 0 6.34315 0 12 0C17.6569 0 20.4853 0 22.2426 1.75736C24 3.51472 24 6.34315 24 12C24 17.6569 24 20.4853 22.2426 22.2426C20.4853 24 17.6569 24 12 24C6.34315 24 3.51472 24 1.75736 22.2426C0 20.4853 0 17.6569 0 12Z" fill="#3370FF"/>
<path d="M9.1753 6.16663H8.47142C7.90603 6.16663 7.46914 6.3415 7.16075 6.70374C6.87806 7.02851 6.73671 7.47819 6.73671 8.04029V10.3761C6.73671 10.7259 6.65961 10.9882 6.50542 11.1631C6.35722 11.3174 6.1131 11.4209 5.77306 11.4665C5.64046 11.4843 5.54169 11.5945 5.54169 11.7246V12.2872C5.54168 12.4111 5.63651 12.5157 5.76296 12.5312C6.10827 12.5735 6.35576 12.6706 6.50542 12.8369C6.65961 12.9992 6.73671 13.2616 6.73671 13.6238V15.9721C6.73671 16.5217 6.87806 16.9714 7.16075 17.2962C7.46914 17.6459 7.90603 17.8333 8.47142 17.8333H9.1753C9.333 17.8333 9.46085 17.709 9.46085 17.5557V17.0991C9.46085 16.9458 9.333 16.8215 9.1753 16.8215H8.70272C8.21443 16.8215 7.98313 16.5467 7.98313 16.0221V13.5613C7.98313 12.8119 7.61049 12.2997 6.87806 12C7.61049 11.7376 7.98313 11.213 7.98313 10.4386V7.99032C7.98313 7.44072 8.21443 7.1784 8.70272 7.1784H9.1753C9.333 7.1784 9.46085 7.05413 9.46085 6.90082V6.44421C9.46085 6.2909 9.333 6.16663 9.1753 6.16663ZM15.5286 6.16663H14.8247C14.667 6.16663 14.5392 6.2909 14.5392 6.44421V6.90082C14.5392 7.05413 14.667 7.1784 14.8247 7.1784H15.2973C15.7728 7.1784 16.0169 7.44072 16.0169 7.99032V10.4386C16.0169 11.213 16.3767 11.7376 17.122 12C16.3767 12.2997 16.0169 12.8119 16.0169 13.5613V16.0221C16.0169 16.5467 15.7728 16.8215 15.2973 16.8215H14.8247C14.667 16.8215 14.5392 16.9458 14.5392 17.0991V17.5557C14.5392 17.709 14.667 17.8333 14.8247 17.8333H15.5286C16.094 17.8333 16.5309 17.6459 16.8393 17.2962C17.122 16.9714 17.2633 16.5217 17.2633 15.9721V13.6238C17.2633 13.2616 17.3404 12.9992 17.4946 12.8369C17.6397 12.6757 17.8767 12.5795 18.2056 12.5352L18.2108 12.5345C18.3525 12.516 18.4583 12.3985 18.4584 12.2594V11.7293C18.4584 11.5966 18.3578 11.4843 18.2226 11.466C17.8852 11.4204 17.6445 11.319 17.5075 11.1755C17.3404 11.0007 17.2633 10.7259 17.2633 10.3761V8.04029C17.2633 7.47819 17.122 7.02851 16.8393 6.70374C16.5309 6.3415 16.094 6.16663 15.5286 6.16663Z" fill="white"/>
<path d="M12.4376 15.0569C12.6746 15.2392 12.9648 15.339 13.2638 15.3409L13.6602 15.3393C13.9355 15.3381 14.1581 15.1145 14.1581 14.8392V14.5434C14.1581 14.2673 13.9343 14.0434 13.6581 14.0434H13.2638C13.2472 14.042 13.2317 14.0352 13.2195 14.024C13.2073 14.0128 13.1991 13.9979 13.1963 13.9816L12.7163 12.2584L14.2266 10.4481C14.2992 10.3608 14.3901 10.2905 14.4927 10.2419C14.6629 10.1614 14.8223 10.0155 14.823 9.82724C14.8237 9.64004 14.8231 9.52311 14.8223 9.38267L14.8223 9.37651C14.8209 9.0998 14.593 8.86972 14.3246 8.93697C14.1939 8.96971 14.0663 9.01525 13.9438 9.07315C13.6695 9.20277 13.4271 9.39118 13.2338 9.625L12.2962 10.75L12.0563 9.88844C11.978 9.59979 11.8072 9.34477 11.5702 9.16241C11.3331 8.98005 11.0428 8.88041 10.7438 8.87875H10.3475C10.0714 8.87875 9.8475 9.10264 9.8475 9.37879V9.67049C9.8475 9.94664 10.0714 10.1706 10.3475 10.1706H10.7438C10.7605 10.1723 10.7762 10.1794 10.7884 10.191C10.8006 10.2025 10.8086 10.2178 10.8113 10.2344L11.2903 11.9584L9.78188 13.7678C9.70951 13.8554 9.61874 13.9261 9.51602 13.9747C9.34634 14.055 9.1875 14.2009 9.1875 14.3886V14.8413C9.1875 15.118 9.41546 15.3481 9.68388 15.2808C9.81457 15.2481 9.94212 15.2026 10.0647 15.1447C10.339 15.015 10.5814 14.8266 10.7747 14.5928L11.7122 13.4678L11.9513 14.3313C12.0298 14.6197 12.2007 14.8746 12.4376 15.0569Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_5696_2019">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -34,6 +34,7 @@ export enum WorkflowType {
LoopContinueNode = 'loop-continue-node',
LoopBreakNode = 'loop-break-node',
VariableSplittingNode = 'variable-splitting-node',
VariableAggregationNode = 'variable-aggregation-node',
VideoUnderstandNode = 'video-understand-node',
ParameterExtractionNode = 'parameter-extraction-node',
}

View File

@ -259,6 +259,10 @@ You are a master of problem optimization, adept at accurately inferring user int
text: 'Update the value of the global variable',
assign: 'Set Value',
},
variableAggregationNode: {
label: 'Variable Aggregation',
text: 'Perform aggregation processing on the outputs of multiple branches',
},
mcpNode: {
label: 'MCP Node',
text: 'Call external MCP services to process data',

View File

@ -261,6 +261,10 @@ export default {
requiredMessage: '请选择图片',
},
},
variableAggregationNode: {
label: '变量聚合',
text: '对多个分支的输出进行聚合处理',
},
variableAssignNode: {
label: '变量赋值',
text: '更新全局变量的值',

View File

@ -259,6 +259,10 @@ export default {
text: '更新全域變數的值',
assign: '賦值',
},
variableAggregationNode: {
label: '變量聚合',
text: '對多個分支的輸出進行聚合處理',
},
mcpNode: {
label: 'MCP 調用',
text: '通過SSE/Streamable HTTP方式執行MCP服務中的工具',

View File

@ -333,6 +333,17 @@ export const videoUnderstandNode = {
},
},
}
export const variableAggregationNode = {
type: WorkflowType.VariableAggregationNode,
text: t('views.applicationWorkflow.nodes.variableAggregationNode.text'),
label: t('views.applicationWorkflow.nodes.variableAggregationNode.label'),
height: 252,
properties: {
stepName: t('views.applicationWorkflow.nodes.variableAggregationNode.label'),
config: {},
},
}
export const variableAssignNode = {
type: WorkflowType.VariableAssignNode,
@ -626,6 +637,8 @@ export const menuNodes = [
list: [conditionNode, formNode, variableAssignNode, replyNode, loopNode],
},
{
label: t('views.applicationWorkflow.nodes.classify.dataProcessing', '数据处理'),
list: [variableSplittingNode, parameterExtractionNode, variableAggregationNode],
label: t('views.applicationWorkflow.nodes.classify.dataProcessing'),
list: [variableSplittingNode, parameterExtractionNode],
},
@ -767,6 +780,7 @@ export const nodeDict: any = {
[WorkflowType.VariableSplittingNode]: variableSplittingNode,
[WorkflowType.VideoUnderstandNode]: videoUnderstandNode,
[WorkflowType.ParameterExtractionNode]: parameterExtractionNode,
[WorkflowType.VariableAggregationNode]: variableAggregationNode,
}
export function isWorkFlow(type: string | undefined) {

View File

@ -0,0 +1,6 @@
<template>
<el-avatar shape="square" style="background: #7F3BF5">
<img src="@/assets/workflow/icon_aggregation.svg" style="width: 100%" alt="" />
</el-avatar>
</template>
<script setup lang="ts"></script>

View File

@ -0,0 +1,15 @@
import VariableAggregationNodeVue from './index.vue'
import { AppNode, AppNodeModel } from '@/workflow/common/app-node'
class VariableAggregationNode extends AppNode {
constructor(props: any) {
super(props, VariableAggregationNodeVue)
}
}
export default {
type: 'variable-aggregation-node',
model: AppNodeModel,
view: VariableAggregationNode,
}

View File

@ -0,0 +1,20 @@
<template>
<div>
<span>变量聚合</span>
</div>
</template>
<script setup lang="ts">
import { set, groupBy, cloneDeep } from 'lodash'
import NodeCascader from '@/workflow/common/NodeCascader.vue'
import NodeContainer from '@/workflow/common/NodeContainer.vue'
import AIModeParamSettingDialog from '@/views/application/component/AIModeParamSettingDialog.vue'
import type { FormInstance } from 'element-plus'
import { ref, computed, onMounted, inject } from 'vue'
import { isLastNode } from '@/workflow/common/data'
import { t } from '@/locales'
import { useRoute } from 'vue-router'
import { randomId } from '@/utils/common'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
</script>
<style lang="scss" scoped></style>