| | |
| | | |
| | | </el-tooltip> --> |
| | | <YWIcon |
| | | class="absolute right-1 top-1 cursor-pointer" |
| | | class="absolute right-4 top-1 cursor-pointer" |
| | | :class="[defaultLanguage !== 'text' ? '!text-gray-300' : '!text-gray-500']" |
| | | name="pingmufangda" |
| | | @click="fullEditCodeClick" |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts" name="CodeEditor"> |
| | | import { computed, onMounted, ref, type PropType } from 'vue'; |
| | | import { computed, ref, type PropType } from 'vue'; |
| | | import { Codemirror } from 'vue-codemirror'; |
| | | import TextEditDialog from '../../dialog/TextEditDialog/index.vue'; |
| | | import type { TextType } from './types'; |
| | |
| | | <div class="relative h-full w-full" id="main-canvas" @drop="handleOnDrop" @dragover="handleOnDragOver"> |
| | | <VueFlow v-model="elements" :node-types="nodeTypes" :connection-mode="ConnectionMode.Strict"> |
| | | <template #node-start="startNodeProps"> |
| | | <StartNode ref="nodeRef" v-bind="startNodeProps" :isViewMode="isViewMode" /> |
| | | <StartNode ref="nodeRef" v-bind="startNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(startNodeProps.id, ref)" /> |
| | | </template> |
| | | <template #node-condition="conditionNodeProps"> |
| | | <ConditionNode ref="nodeRef" v-bind="conditionNodeProps" :isViewMode="isViewMode" /> |
| | | <ConditionNode ref="nodeRef" v-bind="conditionNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(conditionNodeProps.id, ref)" /> |
| | | </template> |
| | | <template #node-output_msg="outputNodeProps"> |
| | | <OutputNode ref="nodeRef" v-bind="outputNodeProps" :isViewMode="isViewMode" /> |
| | | <OutputNode ref="nodeRef" v-bind="outputNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(outputNodeProps.id, ref)" /> |
| | | </template> |
| | | |
| | | <template #node-end="endNodeProps"> |
| | |
| | | </template> |
| | | |
| | | <template #node-agent="agentNodeProps"> |
| | | <AgentNode ref="nodeRef" v-bind="agentNodeProps" :agentNames="agentNames" :isViewMode="isViewMode" /> |
| | | <AgentNode ref="nodeRef" v-bind="agentNodeProps" :agentNames="agentNames" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(agentNodeProps.id, ref)" /> |
| | | </template> |
| | | <template #node-func="funcNodeProps"> |
| | | <FuncNode ref="nodeRef" v-bind="funcNodeProps" :funcNames="funcNames" :isViewMode="isViewMode" /> |
| | | </template> |
| | | |
| | | <template #node-code="codeNodeProps"> |
| | | <CodeNode ref="nodeRef" v-bind="codeNodeProps" :isViewMode="isViewMode" /> |
| | | <CodeNode ref="nodeRef" v-bind="codeNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(codeNodeProps.id, ref)" /> |
| | | </template> |
| | | <template #node-python_code="pythonCodeNodeProps"> |
| | | <PythonCodeNode ref="nodeRef" v-bind="pythonCodeNodeProps" :isViewMode="isViewMode" /> |
| | | <PythonCodeNode ref="nodeRef" v-bind="pythonCodeNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(pythonCodeNodeProps.id, ref)" /> |
| | | </template> |
| | | <template #node-text_resource="textResourceNodeProps"> |
| | | <TextResourceNode ref="nodeRef" v-bind="textResourceNodeProps" :isViewMode="isViewMode" /> |
| | | <TextResourceNode ref="nodeRef" v-bind="textResourceNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(textResourceNodeProps.id, ref)" /> |
| | | </template> |
| | | |
| | | <template #node-analysis="analysisNodeProps"> |
| | |
| | | </template> |
| | | |
| | | <template #node-LLM="llmNodeProps"> |
| | | <LLMNode ref="nodeRef" v-bind="llmNodeProps" :llmInfoList="llmInfoList" :isViewMode="isViewMode" /> |
| | | <LLMNode |
| | | v-bind="llmNodeProps" |
| | | :llmInfoList="llmInfoList" |
| | | :isViewMode="isViewMode" |
| | | @register="(ref) => registerNodeRef(llmNodeProps.id, ref)" |
| | | /> |
| | | </template> |
| | | <Controls :showInteractive="false" /> |
| | | <Background /> |
| | |
| | | } |
| | | } |
| | | |
| | | const nodeRef = ref(); |
| | | const validateForm = () => { |
| | | // nodeRef.value.validateForm(); |
| | | console.log('ð ~ nodeRef.value:', nodeRef.value); |
| | | const nodeRefs = ref(new Map()); |
| | | |
| | | const registerNodeRef = (nodeId: string, ref: any) => { |
| | | nodeRefs.value.set(nodeId, ref); |
| | | }; |
| | | |
| | | const validateForm = async () => { |
| | | const validPromises = []; |
| | | for (const nodeRef of nodeRefs.value.values()) { |
| | | if (nodeRef?.validateForm) { |
| | | validPromises.push(nodeRef.validateForm()); |
| | | } |
| | | } |
| | | |
| | | const results = await Promise.all(validPromises); |
| | | return results; |
| | | }; |
| | | |
| | | defineExpose({ |
| | | validateForm, |
| | | }); |
| | |
| | | key: 'code', |
| | | type: 'code', |
| | | required: true, |
| | | value: 'const main = (arg1, arg2) =>{\n return {\n result1: arg1,\n result2: arg2\n }\n}', |
| | | value: "ar recs = args.querySQL(\n \" SELECT * FROM guangming_data.tc_hzl_v4\"\n + \" WHERE otime >={start_time}::timestamp + '-1 months' AND otime < {end_time}::timestamp + '1 days'\", {\n start_time : args.getArg(\"start_time\"),\n end_time : args.getArg(\"end_time\")\n});\n\nvar resultText = \"æ¶é´,æ°´ååï¼èçµé,åºå£æµé\\n\";\nfor(var recIndex in recs)\n{\n var rec = recs[recIndex];\n resultText += rec[\"OTIME\"] + \",\" + rec[\"FACT_NAME\"] + \",\" + rec[\"VPOWER\"] + \",\" + rec[\"VFLOW\"] + \"\\n\";\n}\nargs.setArg(\"RECORD_LIST\", resultText);\n\nargs.sendTableToClent({\n title : \"æµé\",\n columns : [\n {\"title\":\"æ¶é´\", \"name\":\"OTIME\"},\n {\"title\":\"æ°´å\", \"name\":\"FACT_NAME\"},\n {\"title\":\"æµé\", \"name\":\"VFLOW\"}\n ],\n\n recs : recs\n});\n\nargs.sendChartToClient({\n title : \"çµé\",\n col_time : \"OTIME\",\n col_name : \"FACT_NAME\",\n col_value: \"VPOWER\",\n recs : recs\n});\nargs.sendKnowledgeToClient({\n result : args.getArg(\"num1\") + \" + \" + args.getArg(\"num2\") + \"=\" + args.getArg(\"V\")\n});", |
| | | language: ['text', 'javascript'], |
| | | defaultLanguage: 'javascript', |
| | | }, |
| | |
| | | key: 'code', |
| | | type: 'code', |
| | | required: true, |
| | | value: 'const main = (arg1, arg2) =>{\n return {\n result1: arg1,\n result2: arg2\n }\n}', |
| | | value: `from lib.system import *\n\nargJson = readArgJson()\nrestult = argJson['num1'] + argJson['num2']\nwriteResultText(str(restult))`, |
| | | language: ['python'], |
| | | defaultLanguage: 'python', |
| | | }, |
| | |
| | | :isViewMode="isViewMode" |
| | | > |
| | | <Handle :id="targetHandleId" type="target" :position="Position.Left" /> |
| | | |
| | | <FieldLayout :title="VueFlowHelper.getConfigValue(VueFlowHelper.getGroupParam(data), 'name', '代çåç§°')"> |
| | | <el-select |
| | | class="w-full" |
| | | filterable |
| | | :disabled="isViewMode" |
| | | :placeholder="VueFlowHelper.getConfigValue(agentParams, 'placeholder', '代çåç§°')" |
| | | v-model="agentParams.value" |
| | | @change="agentParamsValueChange" |
| | | > |
| | | <el-option v-for="item in agentNames" :key="item.id" :value="item.id" :label="item.title"></el-option> |
| | | </el-select> |
| | | </FieldLayout> |
| | | |
| | | <el-form ref="formRef" :model="data" :rules="formRules" label-position="right" label-width="60px" :show-message="false"> |
| | | <FieldLayout :title="VueFlowHelper.getConfigValue(VueFlowHelper.getGroupParam(data), 'name', '代çåç§°')"> |
| | | <el-form-item prop="group_params.0.params.0.value" labelWidth="0"> |
| | | <el-select |
| | | class="w-full" |
| | | filterable |
| | | :disabled="isViewMode" |
| | | :placeholder="VueFlowHelper.getConfigValue(agentParams, 'placeholder', '代çåç§°')" |
| | | v-model="agentParams.value" |
| | | clearable |
| | | @change="agentParamsValueChange" |
| | | > |
| | | <el-option v-for="item in agentNames" :key="item.id" :value="item.id" :label="item.title"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </FieldLayout> |
| | | </el-form> |
| | | <Handle :id="sourceHandleId" type="source" :position="Position.Right" /> |
| | | </NodeBasicLayout> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { Handle, Position, useNode } from '@vue-flow/core'; |
| | | import { ref } from 'vue'; |
| | | import { onMounted, ref } from 'vue'; |
| | | import { VueFlowHelper } from '../../VueFlowHelper'; |
| | | |
| | | import { NodeType } from '../../vueFlowEnum'; |
| | | import FieldLayout from './components/FieldLayout.vue'; |
| | | import NodeBasicLayout from './components/NodeBasicLayout.vue'; |
| | | import { validateForm } from './utils'; |
| | | // defineProps<NodeProps<LLMNodeData, LLMNodeEvents>>(); |
| | | |
| | | const props = defineProps({ |
| | |
| | | default: false, |
| | | }, |
| | | }); |
| | | |
| | | const emit = defineEmits<{ |
| | | (e: 'register', data: { validateForm: () => Promise<{ isValid: boolean; invalidFields?: any }> }): void; |
| | | }>(); |
| | | |
| | | const agentParamsValueChange = () => { |
| | | // const foundNames = props.agentNames.find(item=>item.id == agentParams.value); |
| | | // agentParams.value.value_label = foundNames?.title ??''; |
| | |
| | | |
| | | const agentParams = ref(VueFlowHelper.getParams(VueFlowHelper.getGroupParam(data.value), 'agent')); |
| | | VueFlowHelper.getConfigValue(agentParams.value, 'label', ''); |
| | | const formRef = ref(); |
| | | const formRules = ref({ |
| | | 'group_params.0.params.0.value': [{ required: true, message: 'è¯·éæ©ä»£çåç§°', trigger: 'change' }], |
| | | }); |
| | | |
| | | // 注åèç¹å®ä¾ |
| | | onMounted(() => { |
| | | emit('register', { |
| | | validateForm: validateForm(formRef) as any, |
| | | }); |
| | | }); |
| | | </script> |
| | |
| | | <template> |
| | | <NodeBasicLayout |
| | | v-model:title="data.title" |
| | | style="width: 320px" |
| | | :type="NodeType.Code" |
| | | :showOffset="false" |
| | | :description="data.description" |
| | | :isViewMode="isViewMode" |
| | | > |
| | | <Handle :id="targetHandleId" type="target" :position="Position.Left" /> |
| | | <FieldLayout :title="codeInput.name"> |
| | | <div class="flex flex-col gap-y-2"> |
| | | <div :key="subIndex" v-for="(subItem, subIndex) in codeInput.params[0].value" class="flex-items-center gap-x-2 pr-8"> |
| | | <el-input filterable class="w-[120px] flex-0" v-model="subItem.key" placeholder="åæ°å" :readonly="isViewMode"></el-input> |
| | | <el-form ref="formRef" :model="data" :rules="formRules" label-position="right" label-width="60px" :show-message="false"> |
| | | <!-- <FieldLayout :title="codeInput.name"> |
| | | <div class="flex flex-col gap-y-2"> |
| | | <div :key="subIndex" v-for="(subItem, subIndex) in codeInput.params[0].value" class="flex-items-center gap-x-2 pr-8"> |
| | | <el-input filterable class="w-[120px] flex-0" v-model="subItem.key" placeholder="åæ°å" :readonly="isViewMode"></el-input> |
| | | |
| | | <el-input filterable class="w-[120px] flex-0" v-model="subItem.value" placeholder="å¼" :readonly="isViewMode"></el-input> |
| | | <span |
| | | v-if="!isViewMode" |
| | | class="ywifont ywicon-shanchu text-red-400 cursor-pointer" |
| | | @click="delInputVarItem(subIndex)" |
| | | ></span> |
| | | <el-input filterable class="w-[120px] flex-0" v-model="subItem.value" placeholder="å¼" :readonly="isViewMode"></el-input> |
| | | <span |
| | | v-if="!isViewMode" |
| | | class="ywifont ywicon-shanchu text-red-400 cursor-pointer" |
| | | @click="delInputVarItem(subIndex)" |
| | | ></span> |
| | | </div> |
| | | <el-button v-if="!isViewMode" class="w-fit mt-3" type="primary" @click="addInputVarItem">æ·»å æ°çå
¥å</el-button> |
| | | </div> |
| | | <el-button v-if="!isViewMode" class="w-fit mt-3" type="primary" @click="addInputVarItem">æ·»å æ°çå
¥å</el-button> |
| | | </div> |
| | | </FieldLayout> |
| | | <FieldLayout :title="codeStr.name"> |
| | | <CodeEditor |
| | | :title="codeStr.name" |
| | | :language="codeLanguage" |
| | | v-model:defaultLanguage="codeStr.params[0].defaultLanguage" |
| | | v-model:editValue="codeStr.params[0].value" |
| | | :disabled="isViewMode" |
| | | /> |
| | | <template #right> |
| | | <el-select :disabled="isViewMode" size="small" class="w-[100px]" v-model="codeStr.params[0].defaultLanguage"> |
| | | <el-option v-for="item in codeLanguage" :key="item" :value="item" :label="textTypeMap[item]"></el-option> |
| | | </el-select> |
| | | </template> |
| | | </FieldLayout> |
| | | <FieldLayout :title="codeOutput.name"> |
| | | </FieldLayout> --> |
| | | <FieldLayout :title="codeStr.name" required> |
| | | <el-form-item prop="group_params.1.params.0.value" labelWidth="0"> |
| | | <CodeEditor |
| | | class="w-full" |
| | | :title="codeStr.name" |
| | | :language="codeLanguage" |
| | | v-model:defaultLanguage="codeStr.params[0].defaultLanguage" |
| | | v-model:editValue="codeStr.params[0].value" |
| | | :disabled="isViewMode" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <template #right> |
| | | <el-select :disabled="isViewMode" size="small" class="w-[100px]" v-model="codeStr.params[0].defaultLanguage"> |
| | | <el-option v-for="item in codeLanguage" :key="item" :value="item" :label="textTypeMap[item]"></el-option> |
| | | </el-select> |
| | | </template> |
| | | </FieldLayout> |
| | | <!-- <FieldLayout :title="codeOutput.name"> |
| | | <div class="flex flex-col gap-y-2"> |
| | | <div :key="subIndex" v-for="(subItem, subIndex) in codeOutput.params[0].value" class="flex-items-center gap-x-2 pr-8"> |
| | | <el-input :readonly="isViewMode" filterable class="w-[120px] flex-0" v-model="subItem.key" placeholder="åæ°å"> </el-input> |
| | |
| | | </div> |
| | | <el-button v-if="!isViewMode" class="w-fit mt-3" type="primary" @click="addOutputVarItem">æ·»å æ°çåºå</el-button> |
| | | </div> |
| | | </FieldLayout> |
| | | </FieldLayout> --> |
| | | </el-form> |
| | | <Handle :id="sourceHandleId" type="source" :position="Position.Right" /> |
| | | </NodeBasicLayout> |
| | | </template> |
| | |
| | | <script lang="ts" setup> |
| | | import type { NodeProps } from '@vue-flow/core'; |
| | | import { Handle, Position, useNode } from '@vue-flow/core'; |
| | | import { ref } from 'vue'; |
| | | import { onMounted, ref } from 'vue'; |
| | | import { VueFlowHelper } from '../../VueFlowHelper'; |
| | | import { NodeType, ParameterType, parameterTypeMap } from '../../vueFlowEnum'; |
| | | import { NodeType, ParameterType } from '../../vueFlowEnum'; |
| | | import CodeEditor from '/@/components/input/codeEditor/index.vue'; |
| | | // import CodeEditDialog from './components/CodeEditDlg.vue'; |
| | | import FieldLayout from './components/FieldLayout.vue'; |
| | | import NodeBasicLayout from './components/NodeBasicLayout.vue'; |
| | | import type { LLMNodeData, LLMNodeEvents } from './index'; |
| | | import { textTypeMap } from '/@/components/input/codeEditor/types'; |
| | | import { validateForm } from './utils'; |
| | | defineProps< |
| | | NodeProps<LLMNodeData, LLMNodeEvents> & { |
| | | isViewMode?: boolean; |
| | |
| | | const codeOutput = ref(VueFlowHelper.getGroupParam(data.value, 2)); |
| | | |
| | | const codeLanguage = ref(VueFlowHelper.getConfigValue(codeStr.value.params[0], 'language', ['text', 'javascript'])); |
| | | |
| | | const emit = defineEmits<{ |
| | | (e: 'register', data: { validateForm: () => Promise<{ isValid: boolean; invalidFields?: any }> }): void; |
| | | }>(); |
| | | // defaultLanguage ä¸åå¨ï¼è®¾ç½®é»è®¤å¼ |
| | | !codeStr.value.params[0].defaultLanguage && (codeStr.value.params[0].defaultLanguage = 'javascript'); |
| | | |
| | |
| | | } |
| | | codeOutput.value.params[0].value.push(getOutputEmptyItem()); |
| | | }; |
| | | |
| | | const formRef = ref(); |
| | | const formRules = ref({ |
| | | 'group_params.1.params.0.value': [{ required: true, message: '请è¾å
¥æ§è¡ä»£ç ', trigger: 'blur' }], |
| | | }); |
| | | |
| | | // 注åèç¹å®ä¾ |
| | | onMounted(() => { |
| | | emit('register', { |
| | | validateForm: validateForm(formRef) as any, |
| | | }); |
| | | }); |
| | | </script> |
| | |
| | | :isViewMode="isViewMode" |
| | | > |
| | | <Handle :id="leftId" type="target" :position="Position.Left" /> |
| | | <FieldLayout |
| | | v-for="(item, index) in conditionGroupList" |
| | | :key="item.id" |
| | | class="relative group/conditionGroup" |
| | | :title="item.conditions ? '妿' : 'å¦å'" |
| | | > |
| | | <template #right v-if="item.conditions"> |
| | | <el-select v-model="item.operator" class="w-[130px]" :disabled="isViewMode"> |
| | | <el-option |
| | | v-for="item in Object.keys(conditionOperatorMap)" |
| | | :key="item" |
| | | :value="item" |
| | | :label="conditionOperatorMap[item]" |
| | | ></el-option> |
| | | </el-select> |
| | | |
| | | <span |
| | | v-if="!isViewMode" |
| | | class="ywifont ywicon-shanchu text-red-400 invisible group-hover/conditionGroup:visible cursor-pointer" |
| | | @click="delConditionBranch(index)" |
| | | ></span> |
| | | </template> |
| | | <div class="flex flex-col gap-y-2" v-if="item.conditions"> |
| | | <div |
| | | v-for="(subItem, subIndex) in item.conditions" |
| | | :key="subIndex" |
| | | class="ml-5 flex-items-center gap-x-2 group/conditionItem pr-8" |
| | | > |
| | | <el-input :readonly="isViewMode" filterable class="w-[120px] flex-0" v-model="subItem.left_value" placeholder="è¾å
¥åé"> |
| | | </el-input> |
| | | <el-select |
| | | :disabled="isViewMode" |
| | | filterable |
| | | v-model="subItem.comparison_operation" |
| | | class="flex-0 w-[120px]" |
| | | placeholder="éæ©æ¡ä»¶" |
| | | > |
| | | <el-form ref="formRef" :model="data" :rules="formRules" label-width="100px" :show-message="false"> |
| | | <FieldLayout |
| | | v-for="(item, index) in conditionGroupList" |
| | | :key="item.id" |
| | | class="relative group/conditionGroup" |
| | | :title="item.conditions ? '妿' : 'å¦å'" |
| | | > |
| | | <template #right v-if="item.conditions"> |
| | | <el-select v-model="item.operator" class="w-[130px]" :disabled="isViewMode"> |
| | | <el-option |
| | | v-for="operation in Object.keys(compareOperationMap)" |
| | | :key="operation" |
| | | :value="operation" |
| | | :label="compareOperationMap[operation]" |
| | | v-for="item in Object.keys(conditionOperatorMap)" |
| | | :key="item" |
| | | :value="item" |
| | | :label="conditionOperatorMap[item]" |
| | | ></el-option> |
| | | </el-select> |
| | | |
| | | <!-- <el-select v-model="subItem.right_value_type" class="flex-0 w-[90px]" placeholder="è¯·éæ©"> |
| | | <el-option v-for="item in Object.keys(varTypeMap)" :key="item" :value="item" :label="varTypeMap[item]"></el-option> |
| | | </el-select> --> |
| | | <template v-if="isShowRight(subItem)"> |
| | | <el-input |
| | | :readonly="isViewMode" |
| | | v-if="subItem.right_value_type === VarType.Input" |
| | | v-model="subItem.right_value" |
| | | class="w-[180px]" |
| | | placeholder="è¾å
¥å¼" |
| | | > |
| | | </el-input> |
| | | |
| | | <el-tree-select |
| | | v-else |
| | | :disabled="isViewMode" |
| | | filterable |
| | | class="w-[120px] flex-0" |
| | | v-model="subItem.right_value" |
| | | :data="treeReferOptions" |
| | | node-key="id" |
| | | :clearable="true" |
| | | :accordion="false" |
| | | :expandNode="false" |
| | | :check-strictly="false" |
| | | placeholder="éæ©åé" |
| | | > |
| | | </el-tree-select> |
| | | </template> |
| | | |
| | | <span |
| | | v-if="!isViewMode" |
| | | class="ywifont ywicon-shanchu text-red-400 invisible group-hover/conditionItem:visible cursor-pointer" |
| | | @click="delConditionItem(item, subIndex)" |
| | | class="ywifont ywicon-shanchu text-red-400 invisible group-hover/conditionGroup:visible cursor-pointer" |
| | | @click="delConditionBranch(index)" |
| | | ></span> |
| | | </template> |
| | | <div class="flex flex-col gap-y-2" v-if="item.conditions"> |
| | | <div |
| | | v-for="(subItem, subIndex) in item.conditions" |
| | | :key="subIndex" |
| | | class="ml-5 flex-items-center gap-x-2 group/conditionItem pr-8" |
| | | > |
| | | <el-form-item |
| | | class="w-[120px] flex-0 !mb-0" |
| | | labelWidth="0" |
| | | :prop="`group_params.0.params.0.value.${index}.conditions.${subIndex}.left_value`" |
| | | > |
| | | <el-input :readonly="isViewMode" filterable v-model="subItem.left_value" placeholder="è¾å
¥åé"> </el-input> |
| | | </el-form-item> |
| | | <el-form-item |
| | | class="flex-0 w-[120px] !mb-0" |
| | | labelWidth="0" |
| | | :prop="`group_params.0.params.0.value.${index}.conditions.${subIndex}.comparison_operation`" |
| | | > |
| | | <el-select :disabled="isViewMode" filterable v-model="subItem.comparison_operation" placeholder="éæ©æ¡ä»¶"> |
| | | <el-option |
| | | v-for="operation in Object.keys(compareOperationMap)" |
| | | :key="operation" |
| | | :value="operation" |
| | | :label="compareOperationMap[operation]" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <template v-if="isShowRight(subItem)"> |
| | | <el-form-item |
| | | class="w-[180px] !mb-0" |
| | | labelWidth="0" |
| | | :prop="`group_params.0.params.0.value.${index}.conditions.${subIndex}.right_value`" |
| | | > |
| | | <el-input |
| | | :readonly="isViewMode" |
| | | v-if="subItem.right_value_type === VarType.Input" |
| | | v-model="subItem.right_value" |
| | | placeholder="è¾å
¥å¼" |
| | | > |
| | | </el-input> |
| | | |
| | | <el-tree-select |
| | | v-else |
| | | :disabled="isViewMode" |
| | | filterable |
| | | class="w-[120px] flex-0" |
| | | v-model="subItem.right_value" |
| | | :data="treeReferOptions" |
| | | node-key="id" |
| | | :clearable="true" |
| | | :accordion="false" |
| | | :expandNode="false" |
| | | :check-strictly="false" |
| | | placeholder="éæ©åé" |
| | | > |
| | | </el-tree-select> |
| | | </el-form-item> |
| | | </template> |
| | | |
| | | <span |
| | | v-if="!isViewMode" |
| | | class="ywifont ywicon-shanchu text-red-400 invisible group-hover/conditionItem:visible cursor-pointer" |
| | | @click="delConditionItem(item, subIndex)" |
| | | ></span> |
| | | </div> |
| | | <el-button v-if="!isViewMode" class="w-fit mt-3" type="primary" @click="addConditionItem(item)">æ·»å æ¡ä»¶</el-button> |
| | | </div> |
| | | <el-button v-if="!isViewMode" class="w-fit mt-3" type="primary" @click="addConditionItem(item)">æ·»å æ¡ä»¶</el-button> |
| | | </div> |
| | | <div v-else-if="isViewMode" class="h-[24px]"></div> |
| | | <el-button v-else-if="!isViewMode" @click="addConditionBranch" class="w-fit mt-3" type="success">æ·»å 忝</el-button> |
| | | <Handle class="!right-0 !-translate-y-4" :id="item.id" type="source" :position="Position.Right" /> |
| | | </FieldLayout> |
| | | <div v-else-if="isViewMode" class="h-[24px]"></div> |
| | | <el-button v-else-if="!isViewMode" @click="addConditionBranch" class="w-fit mt-3" type="success">æ·»å 忝</el-button> |
| | | <Handle class="!right-0 !-translate-y-4" :id="item.id" type="source" :position="Position.Right" /> |
| | | </FieldLayout> |
| | | </el-form> |
| | | </NodeBasicLayout> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import type { NodeProps } from '@vue-flow/core'; |
| | | import { Handle, Position, useNode, useVueFlow } from '@vue-flow/core'; |
| | | import { computed, ref, watchEffect } from 'vue'; |
| | | import { computed, onMounted, ref, watch, watchEffect } from 'vue'; |
| | | import { ConditionHelper, VueFlowHelper } from '../../VueFlowHelper'; |
| | | import { CompareOperation, NodeType, VarType, compareOperationMap, conditionOperatorMap } from '../../vueFlowEnum'; |
| | | import type { LLMNodeData, LLMNodeEvents } from './index'; |
| | | |
| | | import FieldLayout from './components/FieldLayout.vue'; |
| | | import NodeBasicLayout from './components/NodeBasicLayout.vue'; |
| | | import { validateForm } from './utils'; |
| | | |
| | | const emit = defineEmits<{ |
| | | (e: 'register', data: { validateForm: () => Promise<{ isValid: boolean; invalidFields?: any }> }): void; |
| | | }>(); |
| | | defineProps< |
| | | NodeProps<LLMNodeData, LLMNodeEvents> & { |
| | | isViewMode?: boolean; |
| | |
| | | }); |
| | | |
| | | const data = ref(node.node.data); |
| | | |
| | | const conditionGroupList = ref(VueFlowHelper.getFieldValue(data.value, 'condition')); |
| | | |
| | | const { removeEdges } = useVueFlow(); |
| | |
| | | const edges = node.connectedEdges.value.filter((item) => item.sourceHandle === handleId || item.targetHandle === handleId); |
| | | removeEdges(edges); |
| | | }; |
| | | |
| | | const formRef = ref(); |
| | | |
| | | // æ·»å 表åéªè¯è§å |
| | | const formRules = ref({}); |
| | | |
| | | // æ´æ°éªè¯è§åçæ¹æ³ |
| | | const updateFormRules = () => { |
| | | const rules = {}; |
| | | |
| | | // éåæææ¡ä»¶ç» |
| | | conditionGroupList.value.forEach((group, index) => { |
| | | if (group.conditions) { |
| | | // éåæ¯ä¸ªæ¡ä»¶ç»ä¸çæ¡ä»¶ |
| | | group.conditions.forEach((_, subIndex) => { |
| | | // å·¦å¼éªè¯è§å |
| | | rules[`group_params.0.params.0.value.${index}.conditions.${subIndex}.left_value`] = [ |
| | | { required: true, message: '请è¾å
¥åéå', trigger: 'blur' }, |
| | | ]; |
| | | |
| | | // æ¯è¾æä½ç¬¦éªè¯è§å |
| | | rules[`group_params.0.params.0.value.${index}.conditions.${subIndex}.comparison_operation`] = [ |
| | | { required: true, message: 'è¯·éæ©æ¯è¾æ¡ä»¶', trigger: 'change' }, |
| | | ]; |
| | | |
| | | // å³å¼éªè¯è§å (ä»
å½éè¦å³å¼æ¶éªè¯) |
| | | rules[`group_params.0.params.0.value.${index}.conditions.${subIndex}.right_value`] = [ |
| | | { |
| | | required: true, |
| | | message: '请è¾å
¥æ¯è¾å¼', |
| | | trigger: 'blur', |
| | | validator: (rule, value, callback) => { |
| | | const condition = group.conditions[subIndex]; |
| | | if (isShowRight(condition) && !value) { |
| | | callback(new Error('请è¾å
¥æ¯è¾å¼')); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | }, |
| | | ]; |
| | | }); |
| | | } |
| | | }); |
| | | |
| | | formRules.value = rules; |
| | | }; |
| | | |
| | | const addConditionBranch = () => { |
| | | const conditionGroup = ConditionHelper.getDefaultConditionGroup(); |
| | | // ä¸è½å é¤å
¶ä»åæ¯ |
| | | conditionGroupList.value.splice(-1, 0, conditionGroup); |
| | | updateFormRules(); |
| | | }; |
| | | |
| | | const delConditionBranch = (index) => { |
| | | const group = conditionGroupList.value[index]; |
| | | |
| | | conditionGroupList.value.splice(index, 1); |
| | | removeRelativeHandleEdge(group.id); |
| | | if (conditionGroupList.value.length === 0) { |
| | | addConditionBranch(); |
| | | } |
| | | updateFormRules(); |
| | | }; |
| | | |
| | | const addConditionItem = (group) => { |
| | | const conditionGroup = ConditionHelper.getConditionItem(); |
| | | group.conditions.push(conditionGroup); |
| | | updateFormRules(); |
| | | }; |
| | | |
| | | const delConditionItem = (group, index) => { |
| | | group.conditions.splice(index, 1); |
| | | updateFormRules(); |
| | | }; |
| | | |
| | | // 表åéªè¯æ¹æ³ |
| | | |
| | | |
| | | // 注åèç¹å®ä¾ |
| | | onMounted(() => { |
| | | updateFormRules(); |
| | | emit('register', { |
| | | validateForm: validateForm(formRef) as any, |
| | | }); |
| | | }); |
| | | |
| | | // ç嬿¡ä»¶å表ååæ´æ°è§å |
| | | watch( |
| | | conditionGroupList, |
| | | () => { |
| | | updateFormRules(); |
| | | }, |
| | | { deep: true } |
| | | ); |
| | | </script> |
| | |
| | | :isViewMode="isViewMode" |
| | | > |
| | | <Handle :id="targetHandleId" type="target" :position="Position.Left" /> |
| | | <el-form :model="data" :rules="formRules" label-position="right" label-width="60px" status-icon> |
| | | <el-form ref="formRef" :model="data" :rules="formRules" label-position="right" label-width="60px" :show-message="false"> |
| | | <FieldLayout :title="VueFlowHelper.getConfigValue(modelSetting, 'name', '模å设置')"> |
| | | <div class="w-full flex-items-center gap-x-2"> |
| | | <div class="flex-column gap-y-1.5"> |
| | |
| | | </div> |
| | | </div> |
| | | </FieldLayout> |
| | | <FieldLayout :title="prompt.name"> |
| | | <CodeEditor |
| | | :title="prompt.name" |
| | | class="nowheel" |
| | | v-model:editValue="VueFlowHelper.getParams(prompt, 'prompt').value" |
| | | :maxHeight="180" |
| | | :disabled="isViewMode" |
| | | /> |
| | | <FieldLayout :title="prompt.name" required> |
| | | <el-form-item labelWidth="0" prop="group_params.1.params.0.value"> |
| | | <CodeEditor |
| | | :title="prompt.name" |
| | | class="nowheel w-full" |
| | | v-model:editValue="VueFlowHelper.getParams(prompt, 'prompt').value" |
| | | :maxHeight="180" |
| | | :disabled="isViewMode" |
| | | /> |
| | | </el-form-item> |
| | | </FieldLayout> |
| | | <FieldLayout :title="outputParam.name" > |
| | | <FieldLayout :title="outputParam.name" required> |
| | | <el-form-item labelWidth="0" prop="group_params.2.params.0.value"> |
| | | <el-input |
| | | class="w-full flex-0" |
| | |
| | | <script setup lang="ts"> |
| | | import type { NodeProps } from '@vue-flow/core'; |
| | | import { Handle, Position, useNode } from '@vue-flow/core'; |
| | | import { ref } from 'vue'; |
| | | import { onMounted, ref } from 'vue'; |
| | | import { VueFlowHelper } from '../../VueFlowHelper'; |
| | | import { NodeType } from '../../vueFlowEnum'; |
| | | import FieldLayout from './components/FieldLayout.vue'; |
| | | import NodeBasicLayout from './components/NodeBasicLayout.vue'; |
| | | import type { LLMNodeData, LLMNodeEvents } from './index'; |
| | | import CodeEditor from '/@/components/input/codeEditor/index.vue'; |
| | | import { invalid } from 'moment'; |
| | | import { validateForm } from './utils'; |
| | | |
| | | defineProps< |
| | | NodeProps<LLMNodeData, LLMNodeEvents> & { |
| | |
| | | const targetHandleId = ref(VueFlowHelper.getHandleId(node.node, 'target')); |
| | | |
| | | const data = ref(node.node.data); |
| | | console.log('ð ~ data.value:', data.value); |
| | | const modelSetting = ref(VueFlowHelper.getGroupParam(data.value, 0)); |
| | | const prompt = ref(VueFlowHelper.getGroupParam(data.value, 1)); |
| | | const outputParam = ref(VueFlowHelper.getGroupParam(data.value, 2)); |
| | |
| | | |
| | | const formRules = ref({ |
| | | 'group_params.0.params.0.value': [{ required: true, message: 'è¯·éæ©æ¨¡å', trigger: 'change' }], |
| | | // 'group_params.0.params.1.value': [{ required: true, message: '请è¾å
¥æ¸©åº¦', trigger: 'blur' }], |
| | | // 'group_params.2.params.0.value': [{ required: true, message: '请è¾å
¥è¾åºåæ°å', trigger: 'blur' }], |
| | | 'group_params.1.params.0.value': [{ required: true, message: '请è¾å
¥æç¤ºè¯', trigger: 'blur' }], |
| | | 'group_params.2.params.0.value': [{ required: true, message: '请è¾å
¥è¾åºåæ°å', trigger: 'blur' }], |
| | | |
| | | }); |
| | | |
| | | const emit = defineEmits(['register']); |
| | | const formRef = ref(); |
| | | const validateForm = async () => { |
| | | const valid = await formRef.value.validate(); |
| | | if (valid) { |
| | | console.log('submit!'); |
| | | } |
| | | }; |
| | | |
| | | defineExpose({ |
| | | validateForm, |
| | | // 表åéªè¯æ¹æ³ |
| | | |
| | | // 注åèç¹å®ä¾ |
| | | onMounted(() => { |
| | | emit('register', { |
| | | validateForm: validateForm(formRef), |
| | | }); |
| | | }); |
| | | </script> |
| | |
| | | :isViewMode="isViewMode" |
| | | > |
| | | <Handle :id="targetHandleId" type="target" :position="Position.Left" /> |
| | | <FieldLayout level="2" :title="VueFlowHelper.getParams(outputParams, 'output_msg').label"> |
| | | <CodeEditor |
| | | :title="VueFlowHelper.getParams(outputParams, 'output_msg').label" |
| | | v-model:editValue="VueFlowHelper.getParams(outputParams, 'output_msg').value.msg" |
| | | :maxHeight="180" |
| | | :disabled="isViewMode" |
| | | :placeholder="VueFlowHelper.getParams(outputParams, 'output_msg').placeholder" |
| | | /> |
| | | </FieldLayout> |
| | | <FieldLayout level="2" :title="VueFlowHelper.getParams(outputParams, 'output_result').label"> |
| | | <el-radio-group |
| | | v-model="VueFlowHelper.getParams(outputParams, 'output_result').value.type" |
| | | @change="interactionTypeChange" |
| | | :disabled="isViewMode" |
| | | class="flex-items-center justify-between interaction-radio-group" |
| | | |
| | | > |
| | | <el-radio v-for="item in Object.keys(interactionTypeMap)" :key="item" :value="item"> |
| | | {{ interactionTypeMap[item] }} |
| | | </el-radio> |
| | | </el-radio-group> |
| | | <el-form ref="formRef" :model="data" :rules="formRules" label-position="right" label-width="60px" :show-message="false"> |
| | | <FieldLayout required level="2" :title="VueFlowHelper.getParams(outputParams, 'output_msg').label"> |
| | | <el-form-item labelWidth="0" prop="group_params.0.params.0.value.msg"> |
| | | <CodeEditor |
| | | class="w-full" |
| | | :title="VueFlowHelper.getParams(outputParams, 'output_msg').label" |
| | | v-model:editValue="VueFlowHelper.getParams(outputParams, 'output_msg').value.msg" |
| | | :maxHeight="180" |
| | | :disabled="isViewMode" |
| | | :placeholder="VueFlowHelper.getParams(outputParams, 'output_msg').placeholder" |
| | | /> |
| | | </el-form-item> |
| | | </FieldLayout> |
| | | <FieldLayout level="2" :title="VueFlowHelper.getParams(outputParams, 'output_result').label"> |
| | | <el-radio-group |
| | | v-model="VueFlowHelper.getParams(outputParams, 'output_result').value.type" |
| | | @change="interactionTypeChange" |
| | | :disabled="isViewMode" |
| | | class="flex-items-center justify-between interaction-radio-group" |
| | | > |
| | | <el-radio v-for="item in Object.keys(interactionTypeMap)" :key="item" :value="item"> |
| | | {{ interactionTypeMap[item] }} |
| | | </el-radio> |
| | | </el-radio-group> |
| | | |
| | | <CodeEditor |
| | | title="è¾å
¥å交äº" |
| | | :disabled="isViewMode" |
| | | v-if="VueFlowHelper.getParams(outputParams, 'output_result').value.type === InteractionType.Input" |
| | | v-model:editValue="VueFlowHelper.getParams(outputParams, 'output_result').value.value" |
| | | :maxHeight="150" |
| | | /> |
| | | <CodeEditor |
| | | title="è¾å
¥å交äº" |
| | | :disabled="isViewMode" |
| | | v-if="VueFlowHelper.getParams(outputParams, 'output_result').value.type === InteractionType.Input" |
| | | v-model:editValue="VueFlowHelper.getParams(outputParams, 'output_result').value.value" |
| | | :maxHeight="150" |
| | | /> |
| | | |
| | | <div |
| | | class="self-start w-full flex-col flex items-start gap-2" |
| | | v-else-if="VueFlowHelper.getParams(outputParams, 'output_result').value.type === InteractionType.Select" |
| | | > |
| | | <div class="flex-column gap-2"> |
| | | <div |
| | | class="text-gray-400 cursor-not-allowed border border-solid rounded-lg border-gray-300 py-3 pl-3 pr-2 items-center justify-between flex group/option relative mr-6" |
| | | :key="item.id" |
| | | v-for="(item, index) in VueFlowHelper.getParams(outputParams, 'output_result').options" |
| | | > |
| | | <span>{{ item.label }}</span> |
| | | <span |
| | | @click="delOption(index)" |
| | | class="cursor-pointer group-hover/option:visible invisible ywifont ywicon-shanchu text-red-500" |
| | | ></span> |
| | | <Handle class="absolute !-right-4" :id="item.id" type="source" :position="Position.Right" /> |
| | | <div |
| | | class="self-start w-full flex-col flex items-start gap-2" |
| | | v-else-if="VueFlowHelper.getParams(outputParams, 'output_result').value.type === InteractionType.Select" |
| | | > |
| | | <div class="flex-column gap-2"> |
| | | <div |
| | | class="text-gray-400 cursor-not-allowed border border-solid rounded-lg border-gray-300 py-3 pl-3 pr-2 items-center justify-between flex group/option relative mr-6" |
| | | :key="item.id" |
| | | v-for="(item, index) in VueFlowHelper.getParams(outputParams, 'output_result').options" |
| | | > |
| | | <span>{{ item.label }}</span> |
| | | <span |
| | | @click="delOption(index)" |
| | | class="cursor-pointer group-hover/option:visible invisible ywifont ywicon-shanchu text-red-500" |
| | | ></span> |
| | | <Handle class="absolute !-right-4" :id="item.id" type="source" :position="Position.Right" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-if="isEditStatus" class="flex-items-center w-full"> |
| | | <el-input class="flex-auto" v-model="tmpEditValue"></el-input> |
| | | <el-button class="flex-0 ml-2" type="success" @click="confirmClick">ç¡®å® </el-button> |
| | | <div v-if="isEditStatus" class="flex-items-center w-full"> |
| | | <el-input class="flex-auto" v-model="tmpEditValue"></el-input> |
| | | <el-button class="flex-0 ml-2" type="success" @click="confirmClick">ç¡®å® </el-button> |
| | | </div> |
| | | <el-button v-else type="primary" @click="addOptionClick">æ·»å é项</el-button> |
| | | </div> |
| | | <el-button v-else type="primary" @click="addOptionClick">æ·»å é项</el-button> |
| | | </div> |
| | | <Handle |
| | | v-if=" |
| | | VueFlowHelper.getParams(outputParams, 'output_result').value.type === InteractionType.Input || |
| | | VueFlowHelper.getParams(outputParams, 'output_result').value.type === InteractionType.None |
| | | " |
| | | :id="sourceHandleId" |
| | | type="source" |
| | | :position="Position.Right" |
| | | /> |
| | | </FieldLayout> |
| | | <Handle |
| | | v-if=" |
| | | VueFlowHelper.getParams(outputParams, 'output_result').value.type === InteractionType.Input || |
| | | VueFlowHelper.getParams(outputParams, 'output_result').value.type === InteractionType.None |
| | | " |
| | | :id="sourceHandleId" |
| | | type="source" |
| | | :position="Position.Right" |
| | | /> |
| | | </FieldLayout> |
| | | </el-form> |
| | | </NodeBasicLayout> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { Handle, Position, useNode, useVueFlow } from '@vue-flow/core'; |
| | | import { ref } from 'vue'; |
| | | import { onMounted, ref } from 'vue'; |
| | | import { NodeType } from '../../vueFlowEnum'; |
| | | |
| | | import type { NodeProps } from '@vue-flow/core'; |
| | |
| | | import NodeBasicLayout from './components/NodeBasicLayout.vue'; |
| | | import type { LLMNodeData, LLMNodeEvents } from './index'; |
| | | import CodeEditor from '/@/components/input/codeEditor/index.vue'; |
| | | import { validateForm } from './utils'; |
| | | |
| | | defineProps< |
| | | NodeProps<LLMNodeData, LLMNodeEvents> & { |
| | | isViewMode?: boolean; |
| | | } |
| | | >(); |
| | | |
| | | const emit = defineEmits<{ |
| | | (e: 'register', data: { validateForm: () => Promise<{ isValid: boolean; invalidFields?: any }> }): void; |
| | | }>(); |
| | | const node = useNode(); |
| | | const sourceHandleId = ref(VueFlowHelper.getHandleId(node.node, 'source')); |
| | | const targetHandleId = ref(VueFlowHelper.getHandleId(node.node, 'target')); |
| | | |
| | | const data = ref(node.node.data); |
| | | |
| | | const outputParams = ref(VueFlowHelper.getGroupParam(data.value, 0)); |
| | | |
| | | const { removeEdges } = useVueFlow(); |
| | |
| | | |
| | | const isEditStatus = ref(false); |
| | | const tmpEditValue = ref(''); |
| | | const formRef = ref(); |
| | | const formRules = ref({ |
| | | 'group_params.0.params.0.value.msg': [{ required: true, message: '请è¾å
¥æ¶æ¯å
容', trigger: 'blur' }], |
| | | }); |
| | | |
| | | // 注åèç¹å®ä¾ |
| | | onMounted(() => { |
| | | emit('register', { |
| | | validateForm: validateForm(formRef) as any, |
| | | }); |
| | | }); |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | .interaction-radio-group { |
| | |
| | | <NodeBasicLayout |
| | | v-model:title="data.title" |
| | | :type="NodeType.PythonCode" |
| | | :style="{ width: '320px' }" |
| | | :showOffset="false" |
| | | :description="data.description" |
| | | :isViewMode="isViewMode" |
| | | > |
| | | <Handle :id="targetHandleId" type="target" :position="Position.Left" /> |
| | | <FieldLayout :title="codeInput.name"> |
| | | <!-- codeInput.params[0].value --> |
| | | <el-input filterable class="w-[120px] flex-0" v-model="codeInput.params[0].value.value" placeholder="åæ°å" :readonly="isViewMode"></el-input> |
| | | </FieldLayout> |
| | | <el-form ref="formRef" :model="data" :rules="formRules" label-position="right" label-width="60px" :show-message="false"> |
| | | <FieldLayout :title="codeInput.name"> |
| | | <!-- codeInput.params[0].value --> |
| | | <el-form-item prop="group_params.0.params.0.value.value" labelWidth="0"> |
| | | <el-input |
| | | filterable |
| | | class="w-[120px] flex-0" |
| | | v-model="codeInput.params[0].value.value" |
| | | placeholder="åæ°å" |
| | | :readonly="isViewMode" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </FieldLayout> |
| | | |
| | | <FieldLayout :title="codeOutput.name"> |
| | | <!-- codeOutput.params[0].value --> |
| | | <el-input filterable class="w-[120px] flex-0" v-model="codeOutput.params[0].value.value" placeholder="åæ°å" :readonly="isViewMode"></el-input> |
| | | </FieldLayout> |
| | | <FieldLayout :title="codeOutput.name" required> |
| | | <!-- codeOutput.params[0].value --> |
| | | <el-form-item prop="group_params.1.params.0.value.value" labelWidth="0"> |
| | | <el-input |
| | | filterable |
| | | class="w-[120px] flex-0" |
| | | v-model="codeOutput.params[0].value.value" |
| | | placeholder="åæ°å" |
| | | :readonly="isViewMode" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </FieldLayout> |
| | | |
| | | <FieldLayout :title="codeStr.name"> |
| | | <CodeEditor |
| | | :title="codeStr.name" |
| | | :language="codeLanguage" |
| | | v-model:defaultLanguage="codeStr.params[0].defaultLanguage" |
| | | v-model:editValue="codeStr.params[0].value" |
| | | :disabled="isViewMode" |
| | | /> |
| | | <template #right> |
| | | <el-select :disabled="isViewMode" size="small" class="w-[100px]" v-model="codeStr.params[0].defaultLanguage"> |
| | | <el-option v-for="item in codeLanguage" :key="item" :value="item" :label="textTypeMap[item]"></el-option> |
| | | </el-select> |
| | | </template> |
| | | </FieldLayout> |
| | | <FieldLayout :title="codeStr.name"> |
| | | <el-form-item prop="group_params.2.params.0.value" labelWidth="0"> |
| | | <CodeEditor |
| | | class="w-full" |
| | | :title="codeStr.name" |
| | | :language="codeLanguage" |
| | | v-model:defaultLanguage="codeStr.params[0].defaultLanguage" |
| | | v-model:editValue="codeStr.params[0].value" |
| | | :disabled="isViewMode" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <template #right> |
| | | <el-select :disabled="isViewMode" size="small" class="w-[100px]" v-model="codeStr.params[0].defaultLanguage"> |
| | | <el-option v-for="item in codeLanguage" :key="item" :value="item" :label="textTypeMap[item]"></el-option> |
| | | </el-select> |
| | | </template> |
| | | </FieldLayout> |
| | | </el-form> |
| | | <Handle :id="sourceHandleId" type="source" :position="Position.Right" /> |
| | | </NodeBasicLayout> |
| | | </template> |
| | |
| | | <script lang="ts" setup> |
| | | import type { NodeProps } from '@vue-flow/core'; |
| | | import { Handle, Position, useNode } from '@vue-flow/core'; |
| | | import { ref } from 'vue'; |
| | | import { onMounted, ref } from 'vue'; |
| | | import { VueFlowHelper } from '../../VueFlowHelper'; |
| | | import { NodeType, ParameterType, parameterTypeMap } from '../../vueFlowEnum'; |
| | | import { NodeType, ParameterType } from '../../vueFlowEnum'; |
| | | import CodeEditor from '/@/components/input/codeEditor/index.vue'; |
| | | // import CodeEditDialog from './components/CodeEditDlg.vue'; |
| | | import FieldLayout from './components/FieldLayout.vue'; |
| | | import NodeBasicLayout from './components/NodeBasicLayout.vue'; |
| | | import type { LLMNodeData, LLMNodeEvents } from './index'; |
| | | import { validateForm } from './utils'; |
| | | import { textTypeMap } from '/@/components/input/codeEditor/types'; |
| | | defineProps< |
| | | NodeProps<LLMNodeData, LLMNodeEvents> & { |
| | | isViewMode?: boolean; |
| | | } |
| | | >(); |
| | | const emit = defineEmits<{ |
| | | (e: 'register', data: { validateForm: () => Promise<{ isValid: boolean; invalidFields?: any }> }): void; |
| | | }>(); |
| | | const node = useNode(); |
| | | const targetHandleId = ref(VueFlowHelper.getHandleId(node.node, 'target')); |
| | | const sourceHandleId = ref(VueFlowHelper.getHandleId(node.node, 'source')); |
| | |
| | | } |
| | | codeOutput.value.params[0].value.push(getOutputEmptyItem()); |
| | | }; |
| | | |
| | | const formRef = ref(); |
| | | const formRules = ref({ |
| | | // 'group_params.0.params.0.value.value': [{ required: true, message: '请è¾å
¥å
¥å', trigger: 'blur' }], |
| | | 'group_params.1.params.0.value.value': [{ required: true, message: '请è¾å
¥åºå', trigger: 'blur' }], |
| | | 'group_params.2.params.0.value': [{ required: true, message: '请è¾å
¥æ§è¡ä»£ç ', trigger: 'blur' }], |
| | | }); |
| | | |
| | | // 注åèç¹å®ä¾ |
| | | onMounted(() => { |
| | | emit('register', { |
| | | validateForm: validateForm(formRef) as any, |
| | | }); |
| | | }); |
| | | </script> |
| | |
| | | :description="VueFlowHelper.getConfigValue(data, 'description', '工使µè¿è¡çèµ·å§èç¹ã')" |
| | | :isViewMode="isViewMode" |
| | | > |
| | | <FieldLayout :title="VueFlowHelper.getConfigValue(varListConfig, 'name', 'æµç¨åæ°')"> |
| | | <div v-for="(item, index) in varList" :key="index" class="group/varItem"> |
| | | <FieldLayout level="2" title="åæ°å"> |
| | | <template #right v-if="!isViewMode"> |
| | | <span |
| | | class="ywifont ywicon-shanchu text-red-400 invisible group-hover/varItem:visible cursor-pointer" |
| | | @click="handleClickDeleteBtn(index)" |
| | | ></span> |
| | | </template> |
| | | <el-input v-model="item.name" :readonly="isViewMode"></el-input> |
| | | </FieldLayout> |
| | | <FieldLayout level="2" title="æè¿°"> |
| | | <el-input |
| | | class="nowheel" |
| | | type="textarea" |
| | | :autosize="{ minRows: 2, maxRows: 6 }" |
| | | v-model="item.description" |
| | | :readonly="isViewMode" |
| | | ></el-input> |
| | | </FieldLayout> |
| | | </div> |
| | | <el-form ref="formRef" :model="data" :rules="formRules" label-position="right" label-width="60px" :show-message="false"> |
| | | <FieldLayout :title="VueFlowHelper.getConfigValue(varListConfig, 'name', 'æµç¨åæ°')"> |
| | | <div v-for="(item, index) in varList" :key="index" class="group/varItem"> |
| | | <FieldLayout level="2" title="åæ°å" required> |
| | | <template #right v-if="!isViewMode"> |
| | | <span |
| | | class="ywifont ywicon-shanchu text-red-400 invisible group-hover/varItem:visible cursor-pointer" |
| | | @click="handleClickDeleteBtn(index)" |
| | | ></span> |
| | | </template> |
| | | <el-form-item labelWidth="0" :prop="`group_params.0.params.0.value.${index}.name`"> |
| | | <el-input v-model="item.name" :readonly="isViewMode"></el-input> |
| | | </el-form-item> |
| | | </FieldLayout> |
| | | <FieldLayout level="2" title="æè¿°" required> |
| | | <el-form-item labelWidth="0" :prop="`group_params.0.params.0.value.${index}.description`"> |
| | | <el-input |
| | | class="nowheel" |
| | | type="textarea" |
| | | :autosize="{ minRows: 2, maxRows: 6 }" |
| | | v-model="item.description" |
| | | :readonly="isViewMode" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </FieldLayout> |
| | | </div> |
| | | |
| | | <el-button v-if="!isViewMode" class="w-fit" type="primary" @click="handleClickAddBtn">æ·»å åæ°</el-button> |
| | | </FieldLayout> |
| | | <el-button v-if="!isViewMode" class="w-fit" type="primary" @click="handleClickAddBtn">æ·»å åæ°</el-button> |
| | | </FieldLayout> |
| | | </el-form> |
| | | <Handle :id="handleId" type="source" :position="Position.Right" /> |
| | | </NodeBasicLayout> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { Handle, Position, useNode } from '@vue-flow/core'; |
| | | import { ref } from 'vue'; |
| | | import { onMounted, ref } from 'vue'; |
| | | |
| | | import type { NodeProps } from '@vue-flow/core'; |
| | | import { VueFlowHelper } from '../../VueFlowHelper'; |
| | |
| | | |
| | | import FieldLayout from './components/FieldLayout.vue'; |
| | | import NodeBasicLayout from './components/NodeBasicLayout.vue'; |
| | | import { validateForm } from './utils'; |
| | | |
| | | const emit = defineEmits(['register']); |
| | | |
| | | defineProps< |
| | | NodeProps<LLMNodeData, LLMNodeEvents> & { |
| | | isViewMode?: boolean; |
| | |
| | | const handleId = ref(VueFlowHelper.getHandleId(node.node, 'source')); |
| | | |
| | | const data = ref(node.node.data); |
| | | |
| | | const varList = ref(VueFlowHelper.getFieldValue(data.value, 'var_list')); |
| | | |
| | | function handleClickAddBtn() { |
| | |
| | | type: '', |
| | | isRequired: true, |
| | | }); |
| | | updateFormRules(); |
| | | } |
| | | const varListConfig = ref(VueFlowHelper.getGroupParam(data.value, 0)); |
| | | |
| | |
| | | |
| | | function handleClickDeleteBtn(index: number) { |
| | | varList.value.splice(index, 1); |
| | | updateFormRules(); |
| | | } |
| | | const formRules = ref({ |
| | | ...varList.value.reduce((rules, _, index) => { |
| | | rules[`group_params.0.params.0.value.${index}.name`] = [{ required: true, message: '请è¾å
¥åæ°å', trigger: 'blur' }]; |
| | | rules[`group_params.0.params.0.value.${index}.description`] = [{ required: true, message: '请è¾å
¥åæ°æè¿°', trigger: 'blur' }]; |
| | | return rules; |
| | | }, {}), |
| | | }); |
| | | |
| | | const formRef = ref(); |
| | | |
| | | const updateFormRules = () => { |
| | | formRules.value = { |
| | | ...varList.value.reduce((rules, _, index) => { |
| | | rules[`group_params.0.params.0.value.${index}.name`] = [{ required: true, message: '请è¾å
¥åæ°å', trigger: 'blur' }]; |
| | | rules[`group_params.0.params.0.value.${index}.description`] = [{ required: true, message: '请è¾å
¥åæ°æè¿°', trigger: 'blur' }]; |
| | | return rules; |
| | | }, {}), |
| | | }; |
| | | }; |
| | | |
| | | // 注åèç¹å®ä¾ |
| | | onMounted(() => { |
| | | updateFormRules(); |
| | | emit('register', { |
| | | validateForm: validateForm(formRef), |
| | | }); |
| | | }); |
| | | </script> |
| | |
| | | :isViewMode="isViewMode" |
| | | > |
| | | <Handle :id="targetHandleId" type="target" :position="Position.Left" /> |
| | | <FieldLayout :title="codeInput.name"> |
| | | <el-input class="w-full flex-0" v-model="codeInput.params[0].value" placeholder="åæ°å" :readonly="isViewMode"> </el-input> |
| | | </FieldLayout> |
| | | <FieldLayout :title="codeStr.name"> |
| | | <CodeEditor |
| | | :disabled="isViewMode" |
| | | :title="codeStr.name" |
| | | :language="codeLanguage" |
| | | v-model:defaultLanguage="codeStr.params[0].defaultLanguage" |
| | | v-model:editValue="codeStr.params[0].value" |
| | | :readonly="isViewMode" |
| | | /> |
| | | <template #right> |
| | | <el-select v-if="!isViewMode" size="small" class="w-[100px]" v-model="codeStr.params[0].defaultLanguage"> |
| | | <el-option v-for="item in codeLanguage" :key="item" :value="item" :label="textTypeMap[item]"></el-option> |
| | | </el-select> |
| | | </template> |
| | | </FieldLayout> |
| | | |
| | | <el-form ref="formRef" :model="data" :rules="formRules" label-position="right" label-width="60px" :show-message="false"> |
| | | <FieldLayout :title="codeInput.name" required> |
| | | <el-form-item prop="group_params.0.params.0.value" labelWidth="0"> |
| | | <el-input class="w-full flex-0" v-model="codeInput.params[0].value" placeholder="åæ°å" :readonly="isViewMode"> </el-input> |
| | | </el-form-item> |
| | | </FieldLayout> |
| | | <FieldLayout :title="codeStr.name" required> |
| | | <el-form-item prop="group_params.1.params.0.value" labelWidth="0"> |
| | | <CodeEditor |
| | | class="w-full" |
| | | :disabled="isViewMode" |
| | | :title="codeStr.name" |
| | | :language="codeLanguage" |
| | | v-model:defaultLanguage="codeStr.params[0].defaultLanguage" |
| | | v-model:editValue="codeStr.params[0].value" |
| | | :readonly="isViewMode" |
| | | /> |
| | | </el-form-item> |
| | | <template #right> |
| | | <el-select v-if="!isViewMode" size="small" class="w-[100px]" v-model="codeStr.params[0].defaultLanguage"> |
| | | <el-option v-for="item in codeLanguage" :key="item" :value="item" :label="textTypeMap[item]"></el-option> |
| | | </el-select> |
| | | </template> |
| | | </FieldLayout> |
| | | </el-form> |
| | | <Handle :id="sourceHandleId" type="source" :position="Position.Right" /> |
| | | </NodeBasicLayout> |
| | | </template> |
| | |
| | | import { vscodeDark } from '@uiw/codemirror-theme-vscode'; |
| | | import type { NodeProps } from '@vue-flow/core'; |
| | | import { Handle, Position, useNode } from '@vue-flow/core'; |
| | | import { ref } from 'vue'; |
| | | import { onMounted, ref } from 'vue'; |
| | | import { VueFlowHelper } from '../../VueFlowHelper'; |
| | | import { NodeType, ParameterType } from '../../vueFlowEnum'; |
| | | import FieldLayout from './components/FieldLayout.vue'; |
| | |
| | | import type { LLMNodeData, LLMNodeEvents } from './index'; |
| | | import CodeEditor from '/@/components/input/codeEditor/index.vue'; |
| | | import { textTypeMap } from '/@/components/input/codeEditor/types'; |
| | | import { validateForm } from './utils'; |
| | | |
| | | defineProps< |
| | | NodeProps<LLMNodeData, LLMNodeEvents> & { |
| | | isViewMode?: boolean; |
| | | } |
| | | >(); |
| | | const emit = defineEmits<{ |
| | | (e: 'register', data: { validateForm: () => Promise<{ isValid: boolean; invalidFields?: any }> }): void; |
| | | }>(); |
| | | const node = useNode(); |
| | | const targetHandleId = ref(VueFlowHelper.getHandleId(node.node, 'target')); |
| | | const sourceHandleId = ref(VueFlowHelper.getHandleId(node.node, 'source')); |
| | |
| | | } |
| | | codeInput.value.params[0].value.push(getInputEmptyItem()); |
| | | }; |
| | | |
| | | const formRef = ref(); |
| | | const formRules = ref({ |
| | | 'group_params.0.params.0.value': [{ required: true, message: '请è¾å
¥åæ°å', trigger: 'blur' }], |
| | | 'group_params.1.params.0.value': [{ required: true, message: '请è¾å
¥åæ°å¼', trigger: 'blur' }], |
| | | }); |
| | | |
| | | // 注åèç¹å®ä¾ |
| | | onMounted(() => { |
| | | emit('register', { |
| | | validateForm: validateForm(formRef) as any, |
| | | }); |
| | | }); |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export const validateForm = (formRef: any) => { |
| | | return () => |
| | | new Promise((resolve, reject) => { |
| | | if (!formRef.value) resolve({ isValid: true }); |
| | | |
| | | try { |
| | | formRef.value.validate((isValid, invalidFields) => { |
| | | resolve({ isValid, invalidFields }); |
| | | }); |
| | | } catch (error) { |
| | | resolve({ isValid: false }); |
| | | } |
| | | }); |
| | | }; |
| | |
| | | <template> |
| | | <div class="absolute bottom-0 left-0 right-0 top-0 bg-page text-base"> |
| | | <div class="relative flex h-full w-full flex-col"> |
| | | <Header :isViewMode="isViewMode" v-if="flowAgent" :flowAgent="flowAgent" :queryId="queryId" @saveClick="validateForm" /> |
| | | <Header :isViewMode="isViewMode" v-if="flowAgent" :flowAgent="flowAgent" :queryId="queryId" @saveClick="saveClick" /> |
| | | <main class="relative flex h-full w-full flex-1"> |
| | | <Sidebar v-if="!isViewMode" class="w-52" @dragstart="handleOnDragStart" /> |
| | | <div class="relative h-full flex-1 overflow-hidden" v-if="flowJson"> |
| | |
| | | import { useVueFlow } from '@vue-flow/core'; |
| | | import { useClipboard } from '@vueuse/core'; |
| | | // import MainCanvas from '@/components/vue-flow/MainCanvas.vue'; |
| | | import { computed, onMounted, ref } from 'vue'; |
| | | import { ElMessage } from 'element-plus'; |
| | | import { computed, h, onMounted, ref } from 'vue'; |
| | | import Header from './components/Header.vue'; |
| | | import Sidebar from './components/Sidebar.vue'; |
| | | import { |
| | | get_agent_names, |
| | | get_flow_func_names, |
| | | get_llm_info_list, |
| | | get_workflow_agent_list, |
| | | get_workflow_json_flow, |
| | | get_llm_info_list, |
| | | update_workflow_json_flow, |
| | | } from '/@/api/workflow'; |
| | | import MainCanvas from '/@/components/vue-flow/MainCanvas.vue'; |
| | | import router from '/@/router'; |
| | | import { useCompRef } from '/@/utils/types'; |
| | | const props = defineProps<{ |
| | | isViewMode: { |
| | | type: Boolean; |
| | |
| | | llmInfoList.value = logicTree; |
| | | }; |
| | | |
| | | const mainCanvasRef = ref(); |
| | | const validateForm = () => { |
| | | mainCanvasRef.value.validateForm(); |
| | | }; |
| | | const mainCanvasRef = useCompRef(MainCanvas); |
| | | const saveClick = async (jsonStr: string) => { |
| | | const results = await mainCanvasRef.value.validateForm(); |
| | | const isValid = results.every((item) => item.isValid); |
| | | if (!isValid) { |
| | | const messageSet = new Set(); |
| | | const invalidFields = results.filter((item) => !item.isValid); |
| | | for (const item of invalidFields) { |
| | | for (const fieldArray of Object.values(item.invalidFields) as any[]) { |
| | | for (const field of fieldArray) { |
| | | field.message && messageSet.add(field.message); |
| | | } |
| | | } |
| | | } |
| | | // ä½¿ç¨ h æ¹æ³å建带æ¢è¡çæ¶æ¯å
容 |
| | | ElMessage({ |
| | | type: 'error', |
| | | message: h( |
| | | 'div', |
| | | { |
| | | style: { |
| | | color: '#f56c6c', // Element Plus é»è®¤éè¯¯æ¶æ¯ççº¢è² |
| | | fontSize: '14px', |
| | | lineHeight: '21px', |
| | | }, |
| | | }, |
| | | [ |
| | | ...Array.from(messageSet).slice(0, 5).map((msg) => |
| | | h( |
| | | 'div', |
| | | { |
| | | style: { |
| | | marginBottom: '4px', |
| | | }, |
| | | }, |
| | | msg as any |
| | | ) |
| | | ), |
| | | ] |
| | | ), |
| | | duration: 3000, |
| | | }); |
| | | // ElMessage.error('cesadfsadf') |
| | | return; |
| | | } |
| | | |
| | | const res = await update_workflow_json_flow({ |
| | | agent_id: queryId.value, |
| | | json_flow: jsonStr, |
| | | }); |
| | | |
| | | ElMessage.success('ä¿åæåï¼'); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | if (!queryId.value) return; |
| | |
| | | const obj = toObject(); |
| | | const jsonStr = obj ? JSONFormat(obj) : ''; |
| | | |
| | | const res = await update_workflow_json_flow({ |
| | | agent_id: props.queryId, |
| | | json_flow: jsonStr, |
| | | }); |
| | | ElMessage.success('ä¿åæåï¼'); |
| | | emit('saveClick'); |
| | | |
| | | emit('saveClick',jsonStr); |
| | | }; |
| | | |
| | | onChange((file) => { |