ENH(ui): enhance check list (#21932)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -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'
|
||||||
@@ -33,6 +34,8 @@ import type { KnowledgeRetrievalNodeType } from '../nodes/knowledge-retrieval/ty
|
|||||||
import type { DataSet } from '@/models/datasets'
|
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 { 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()
|
||||||
@@ -45,6 +48,8 @@ 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)
|
||||||
|
|
||||||
|
const map = useNodesAvailableVarList(nodes)
|
||||||
|
|
||||||
const getCheckData = useCallback((data: CommonNodeType<{}>) => {
|
const getCheckData = useCallback((data: CommonNodeType<{}>) => {
|
||||||
let checkData = data
|
let checkData = data
|
||||||
if (data.type === BlockEnum.KnowledgeRetrieval) {
|
if (data.type === BlockEnum.KnowledgeRetrieval) {
|
||||||
@@ -70,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
|
||||||
@@ -84,8 +90,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
|
|||||||
if (provider_type === CollectionType.workflow)
|
if (provider_type === CollectionType.workflow)
|
||||||
toolIcon = workflowTools.find(tool => tool.id === node.data.provider_id)?.icon
|
toolIcon = workflowTools.find(tool => tool.id === node.data.provider_id)?.icon
|
||||||
}
|
}
|
||||||
|
else if (node.data.type === BlockEnum.Agent) {
|
||||||
if (node.data.type === BlockEnum.Agent) {
|
|
||||||
const data = node.data as AgentNodeType
|
const data = node.data as AgentNodeType
|
||||||
const isReadyForCheckValid = !!strategyProviders
|
const isReadyForCheckValid = !!strategyProviders
|
||||||
const provider = strategyProviders?.find(provider => provider.declaration.identity.name === data.agent_strategy_provider_name)
|
const provider = strategyProviders?.find(provider => provider.declaration.identity.name === data.agent_strategy_provider_name)
|
||||||
@@ -97,10 +102,34 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
|
|||||||
isReadyForCheckValid,
|
isReadyForCheckValid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
usedVars = getNodeUsedVars(node).filter(v => v.length > 0)
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
for (const variable of usedVars) {
|
||||||
|
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({
|
||||||
|
@@ -0,0 +1,75 @@
|
|||||||
|
import {
|
||||||
|
useIsChatMode,
|
||||||
|
useWorkflow,
|
||||||
|
useWorkflowVariables,
|
||||||
|
} from '@/app/components/workflow/hooks'
|
||||||
|
import { BlockEnum, type Node, type NodeOutPutVar, type ValueSelector, type Var } from '@/app/components/workflow/types'
|
||||||
|
type Params = {
|
||||||
|
onlyLeafNodeVar?: boolean
|
||||||
|
hideEnv?: boolean
|
||||||
|
hideChatVar?: boolean
|
||||||
|
filterVar: (payload: Var, selector: ValueSelector) => boolean
|
||||||
|
passedInAvailableNodes?: Node[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const getNodeInfo = (nodeId: string, nodes: Node[]) => {
|
||||||
|
const allNodes = nodes
|
||||||
|
const node = allNodes.find(n => n.id === nodeId)
|
||||||
|
const isInIteration = !!node?.data.isInIteration
|
||||||
|
const isInLoop = !!node?.data.isInLoop
|
||||||
|
const parentNodeId = node?.parentId
|
||||||
|
const parentNode = allNodes.find(n => n.id === parentNodeId)
|
||||||
|
return {
|
||||||
|
node,
|
||||||
|
isInIteration,
|
||||||
|
isInLoop,
|
||||||
|
parentNode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: loop type?
|
||||||
|
const useNodesAvailableVarList = (nodes: Node[], {
|
||||||
|
onlyLeafNodeVar,
|
||||||
|
filterVar,
|
||||||
|
hideEnv = false,
|
||||||
|
hideChatVar = false,
|
||||||
|
passedInAvailableNodes,
|
||||||
|
}: Params = {
|
||||||
|
onlyLeafNodeVar: false,
|
||||||
|
filterVar: () => true,
|
||||||
|
}) => {
|
||||||
|
const { getTreeLeafNodes, getBeforeNodesInSameBranchIncludeParent } = useWorkflow()
|
||||||
|
const { getNodeAvailableVars } = useWorkflowVariables()
|
||||||
|
const isChatMode = useIsChatMode()
|
||||||
|
|
||||||
|
const nodeAvailabilityMap: { [key: string ]: { availableVars: NodeOutPutVar[], availableNodes: Node[] } } = {}
|
||||||
|
|
||||||
|
nodes.forEach((node) => {
|
||||||
|
const nodeId = node.id
|
||||||
|
const availableNodes = passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranchIncludeParent(nodeId))
|
||||||
|
if (node.data.type === BlockEnum.Loop)
|
||||||
|
availableNodes.push(node)
|
||||||
|
|
||||||
|
const {
|
||||||
|
parentNode: iterationNode,
|
||||||
|
} = getNodeInfo(nodeId, nodes)
|
||||||
|
|
||||||
|
const availableVars = getNodeAvailableVars({
|
||||||
|
parentNode: iterationNode,
|
||||||
|
beforeNodes: availableNodes,
|
||||||
|
isChatMode,
|
||||||
|
filterVar,
|
||||||
|
hideEnv,
|
||||||
|
hideChatVar,
|
||||||
|
})
|
||||||
|
const result = {
|
||||||
|
node,
|
||||||
|
availableVars,
|
||||||
|
availableNodes,
|
||||||
|
}
|
||||||
|
nodeAvailabilityMap[nodeId] = result
|
||||||
|
})
|
||||||
|
return nodeAvailabilityMap
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useNodesAvailableVarList
|
@@ -948,9 +948,7 @@ export const getNodeUsedVars = (node: Node): ValueSelector[] => {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
case BlockEnum.Answer: {
|
case BlockEnum.Answer: {
|
||||||
res = (data as AnswerNodeType).variables?.map((v) => {
|
res = matchNotSystemVars([(data as AnswerNodeType).answer])
|
||||||
return v.value_selector
|
|
||||||
})
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case BlockEnum.LLM: {
|
case BlockEnum.LLM: {
|
||||||
|
Reference in New Issue
Block a user