fix(workflow): handle loop node vars and validate variable usage

- Add loop node to available nodes for variable access
- Validate variable usage in nodes and show error for invalid vars
pull/21932/head
Mminamiyama 11 months ago
parent 579bc0f7c5
commit f1643e182e

@ -9,6 +9,7 @@ import type {
CommonNodeType, CommonNodeType,
Edge, Edge,
Node, Node,
ValueSelector,
} from '../types' } from '../types'
import { BlockEnum } from '../types' import { BlockEnum } from '../types'
import { useStore } from '../store' import { useStore } from '../store'
@ -34,6 +35,7 @@ import type { DataSet } from '@/models/datasets'
import { fetchDatasets } from '@/service/datasets' import { fetchDatasets } from '@/service/datasets'
import { MAX_TREE_DEPTH } from '@/config' import { MAX_TREE_DEPTH } from '@/config'
import useNodesAvailableVarList from './use-nodes-available-var-list' import useNodesAvailableVarList from './use-nodes-available-var-list'
import { getNodeUsedVars, isConversationVar, isENV, isSystemVar } from '../nodes/_base/components/variable/utils'
export const useChecklist = (nodes: Node[], edges: Edge[]) => { export const useChecklist = (nodes: Node[], edges: Edge[]) => {
const { t } = useTranslation() const { t } = useTranslation()
@ -46,9 +48,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
const { data: strategyProviders } = useStrategyProviders() const { data: strategyProviders } = useStrategyProviders()
const datasetsDetail = useDatasetsDetailStore(s => s.datasetsDetail) const datasetsDetail = useDatasetsDetailStore(s => s.datasetsDetail)
console.log('==========================nodes: ', nodes)
const map = useNodesAvailableVarList(nodes) const map = useNodesAvailableVarList(nodes)
console.log('==========================map: ', map)
const getCheckData = useCallback((data: CommonNodeType<{}>) => { const getCheckData = useCallback((data: CommonNodeType<{}>) => {
let checkData = data let checkData = data
@ -75,6 +75,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
const node = nodes[i] const node = nodes[i]
let toolIcon let toolIcon
let moreDataForCheckValid let moreDataForCheckValid
let usedVars: ValueSelector[] = []
if (node.data.type === BlockEnum.Tool) { if (node.data.type === BlockEnum.Tool) {
const { provider_type } = node.data const { provider_type } = node.data
@ -102,15 +103,33 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
} }
} }
else { else {
moreDataForCheckValid = { usedVars = getNodeUsedVars(node).filter(v => v.length > 0)
node,
...map[node.id],
}
} }
if (node.type === CUSTOM_NODE) { if (node.type === CUSTOM_NODE) {
const checkData = getCheckData(node.data) const checkData = getCheckData(node.data)
const { errorMessage } = nodesExtraData[node.data.type].checkValid(checkData, t, moreDataForCheckValid) let { errorMessage } = nodesExtraData[node.data.type].checkValid(checkData, t, moreDataForCheckValid)
if (!errorMessage) {
const availableVars = map[node.id].availableVars
usedVars.forEach((variable) => {
const isEnv = isENV(variable)
const isConvVar = isConversationVar(variable)
const isSysVar = isSystemVar(variable)
if (!isEnv && !isConvVar && !isSysVar) {
const usedNode = availableVars.find(v => v.nodeId === variable?.[0])
if (usedNode) {
const usedVar = usedNode.vars.find(v => v.variable === variable?.[1])
if (!usedVar)
errorMessage = t('workflow.errorMsg.invalidVariable')
}
else {
errorMessage = t('workflow.errorMsg.invalidVariable')
}
}
})
}
if (errorMessage || !validNodes.find(n => n.id === node.id)) { if (errorMessage || !validNodes.find(n => n.id === node.id)) {
list.push({ list.push({

@ -3,7 +3,7 @@ import {
useWorkflow, useWorkflow,
useWorkflowVariables, useWorkflowVariables,
} from '@/app/components/workflow/hooks' } from '@/app/components/workflow/hooks'
import type { Node, NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types' import { BlockEnum, type Node, type NodeOutPutVar, type ValueSelector, type Var } from '@/app/components/workflow/types'
type Params = { type Params = {
onlyLeafNodeVar?: boolean onlyLeafNodeVar?: boolean
hideEnv?: boolean hideEnv?: boolean
@ -47,6 +47,8 @@ const useNodesAvailableVarList = (nodes: Node[], {
nodes.forEach((node) => { nodes.forEach((node) => {
const nodeId = node.id const nodeId = node.id
const availableNodes = passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranchIncludeParent(nodeId)) const availableNodes = passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranchIncludeParent(nodeId))
if (node.data.type === BlockEnum.Loop)
availableNodes.push(node)
const { const {
parentNode: iterationNode, parentNode: iterationNode,
@ -60,7 +62,6 @@ const useNodesAvailableVarList = (nodes: Node[], {
hideEnv, hideEnv,
hideChatVar, hideChatVar,
}) })
const result = { const result = {
node, node,
availableVars, availableVars,

Loading…
Cancel
Save