| import type { ValueSelector } from '@/app/components/workflow/types' | import type { ValueSelector } from '@/app/components/workflow/types' | ||||
| import type { VarInInspect } from '@/types/workflow' | import type { VarInInspect } from '@/types/workflow' | ||||
| import { VarInInspectType } from '@/types/workflow' | import { VarInInspectType } from '@/types/workflow' | ||||
| import { useCallback } from 'react' | import { useCallback } from 'react' | ||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { | |||||
| isConversationVar, | |||||
| isENV, | |||||
| isSystemVar, | |||||
| toNodeOutputVars, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import produce from 'immer' | import produce from 'immer' | ||||
| import type { Node } from '@/app/components/workflow/types' | import type { Node } from '@/app/components/workflow/types' | ||||
| import { useNodesInteractionsWithoutSync } from '@/app/components/workflow/hooks/use-nodes-interactions-without-sync' | import { useNodesInteractionsWithoutSync } from '@/app/components/workflow/hooks/use-nodes-interactions-without-sync' | ||||
| import { useEdgesInteractionsWithoutSync } from '@/app/components/workflow/hooks/use-edges-interactions-without-sync' | import { useEdgesInteractionsWithoutSync } from '@/app/components/workflow/hooks/use-edges-interactions-without-sync' | ||||
| import type { FlowType } from '@/types/common' | import type { FlowType } from '@/types/common' | ||||
| import useFLow from '@/service/use-flow' | import useFLow from '@/service/use-flow' | ||||
| import useMatchSchemaType from '../nodes/_base/components/variable/use-match-schema-type' | |||||
| import { useStoreApi } from 'reactflow' | |||||
| type Params = { | type Params = { | ||||
| flowId: string | flowId: string | ||||
| flowType, | flowType, | ||||
| }: Params) => { | }: Params) => { | ||||
| const workflowStore = useWorkflowStore() | const workflowStore = useWorkflowStore() | ||||
| const store = useStoreApi() | |||||
| const { schemaTypeDefinitions } = useMatchSchemaType() | |||||
| const { | const { | ||||
| useInvalidateConversationVarValues, | useInvalidateConversationVarValues, | ||||
| useInvalidateSysVarValues, | useInvalidateSysVarValues, | ||||
| if (!node) | if (!node) | ||||
| return undefined | return undefined | ||||
| const varId = node.vars.find((varItem) => { | const varId = node.vars.find((varItem) => { | ||||
| return varItem.selector[1] === varName | |||||
| })?.id | |||||
| return varId | |||||
| return varItem.selector[1] === varName | |||||
| })?.id | |||||
| return varId | |||||
| }, [getNodeInspectVars]) | }, [getNodeInspectVars]) | ||||
| const getInspectVar = useCallback((nodeId: string, name: string): VarInInspect | undefined => { | const getInspectVar = useCallback((nodeId: string, name: string): VarInInspect | undefined => { | ||||
| }, [getNodeInspectVars]) | }, [getNodeInspectVars]) | ||||
| const hasSetInspectVar = useCallback((nodeId: string, name: string, sysVars: VarInInspect[], conversationVars: VarInInspect[]) => { | const hasSetInspectVar = useCallback((nodeId: string, name: string, sysVars: VarInInspect[], conversationVars: VarInInspect[]) => { | ||||
| const isEnv = isENV([nodeId]) | |||||
| if (isEnv) // always have value | |||||
| return true | |||||
| const isSys = isSystemVar([nodeId]) | |||||
| if (isSys) | |||||
| return sysVars.some(varItem => varItem.selector?.[1]?.replace('sys.', '') === name) | |||||
| const isChatVar = isConversationVar([nodeId]) | |||||
| if (isChatVar) | |||||
| return conversationVars.some(varItem => varItem.selector?.[1] === name) | |||||
| return getInspectVar(nodeId, name) !== undefined | |||||
| const isEnv = isENV([nodeId]) | |||||
| if (isEnv) // always have value | |||||
| return true | |||||
| const isSys = isSystemVar([nodeId]) | |||||
| if (isSys) | |||||
| return sysVars.some(varItem => varItem.selector?.[1]?.replace('sys.', '') === name) | |||||
| const isChatVar = isConversationVar([nodeId]) | |||||
| if (isChatVar) | |||||
| return conversationVars.some(varItem => varItem.selector?.[1] === name) | |||||
| return getInspectVar(nodeId, name) !== undefined | |||||
| }, [getInspectVar]) | }, [getInspectVar]) | ||||
| const hasNodeInspectVars = useCallback((nodeId: string) => { | const hasNodeInspectVars = useCallback((nodeId: string) => { | ||||
| const fetchInspectVarValue = useCallback(async (selector: ValueSelector) => { | const fetchInspectVarValue = useCallback(async (selector: ValueSelector) => { | ||||
| const { | const { | ||||
| setNodeInspectVars, | setNodeInspectVars, | ||||
| buildInTools, | |||||
| customTools, | |||||
| workflowTools, | |||||
| mcpTools, | |||||
| dataSourceList, | |||||
| } = workflowStore.getState() | } = workflowStore.getState() | ||||
| const nodeId = selector[0] | const nodeId = selector[0] | ||||
| const isSystemVar = nodeId === 'sys' | const isSystemVar = nodeId === 'sys' | ||||
| invalidateConversationVarValues() | invalidateConversationVarValues() | ||||
| return | return | ||||
| } | } | ||||
| const { getNodes } = store.getState() | |||||
| const nodeArr = getNodes() | |||||
| const currentNode = nodeArr.find(node => node.id === nodeId) | |||||
| const allPluginInfoList = { | |||||
| buildInTools, | |||||
| customTools, | |||||
| workflowTools, | |||||
| mcpTools, | |||||
| dataSourceList: dataSourceList ?? [], | |||||
| } | |||||
| const currentNodeOutputVars = toNodeOutputVars([currentNode], false, () => true, [], [], [], allPluginInfoList, schemaTypeDefinitions) | |||||
| const vars = await fetchNodeInspectVars(flowType, flowId, nodeId) | const vars = await fetchNodeInspectVars(flowType, flowId, nodeId) | ||||
| setNodeInspectVars(nodeId, vars) | |||||
| const varsWithSchemaType = vars.map((varItem) => { | |||||
| const schemaType = currentNodeOutputVars[0].vars.find(v => v.variable === varItem.name)?.schemaType || '' | |||||
| return { | |||||
| ...varItem, | |||||
| schemaType, | |||||
| } | |||||
| }) | |||||
| setNodeInspectVars(nodeId, varsWithSchemaType) | |||||
| }, [workflowStore, flowType, flowId, invalidateSysVarValues, invalidateConversationVarValues]) | }, [workflowStore, flowType, flowId, invalidateSysVarValues, invalidateConversationVarValues]) | ||||
| // after last run would call this | // after last run would call this | ||||
| } = workflowStore.getState() | } = workflowStore.getState() | ||||
| const nodes = produce(nodesWithInspectVars, (draft) => { | const nodes = produce(nodesWithInspectVars, (draft) => { | ||||
| const nodeInfo = allNodes.find(node => node.id === nodeId) | const nodeInfo = allNodes.find(node => node.id === nodeId) | ||||
| if (nodeInfo) { | |||||
| const index = draft.findIndex(node => node.nodeId === nodeId) | |||||
| if (index === -1) { | |||||
| draft.unshift({ | |||||
| nodeId, | |||||
| nodeType: nodeInfo.data.type, | |||||
| title: nodeInfo.data.title, | |||||
| vars: payload, | |||||
| nodePayload: nodeInfo.data, | |||||
| }) | |||||
| } | |||||
| else { | |||||
| draft[index].vars = payload | |||||
| // put the node to the topAdd commentMore actions | |||||
| draft.unshift(draft.splice(index, 1)[0]) | |||||
| } | |||||
| if (nodeInfo) { | |||||
| const index = draft.findIndex(node => node.nodeId === nodeId) | |||||
| if (index === -1) { | |||||
| draft.unshift({ | |||||
| nodeId, | |||||
| nodeType: nodeInfo.data.type, | |||||
| title: nodeInfo.data.title, | |||||
| vars: payload, | |||||
| nodePayload: nodeInfo.data, | |||||
| }) | |||||
| } | |||||
| else { | |||||
| draft[index].vars = payload | |||||
| // put the node to the topAdd commentMore actions | |||||
| draft.unshift(draft.splice(index, 1)[0]) | |||||
| } | } | ||||
| } | |||||
| }) | }) | ||||
| setNodesWithInspectVars(nodes) | setNodesWithInspectVars(nodes) | ||||
| handleCancelNodeSuccessStatus(nodeId) | handleCancelNodeSuccessStatus(nodeId) | ||||
| const hasNodeInspectVar = useCallback((nodeId: string, varId: string) => { | const hasNodeInspectVar = useCallback((nodeId: string, varId: string) => { | ||||
| const { nodesWithInspectVars } = workflowStore.getState() | const { nodesWithInspectVars } = workflowStore.getState() | ||||
| const targetNode = nodesWithInspectVars.find(item => item.nodeId === nodeId) | const targetNode = nodesWithInspectVars.find(item => item.nodeId === nodeId) | ||||
| if(!targetNode || !targetNode.vars) | |||||
| if (!targetNode || !targetNode.vars) | |||||
| return false | return false | ||||
| return targetNode.vars.some(item => item.id === varId) | return targetNode.vars.some(item => item.id === varId) | ||||
| }, [workflowStore]) | }, [workflowStore]) | ||||
| const deleteInspectVar = useCallback(async (nodeId: string, varId: string) => { | const deleteInspectVar = useCallback(async (nodeId: string, varId: string) => { | ||||
| const { deleteInspectVar } = workflowStore.getState() | const { deleteInspectVar } = workflowStore.getState() | ||||
| if(hasNodeInspectVar(nodeId, varId)) { | |||||
| if (hasNodeInspectVar(nodeId, varId)) { | |||||
| await doDeleteInspectVar(varId) | await doDeleteInspectVar(varId) | ||||
| deleteInspectVar(nodeId, varId) | deleteInspectVar(nodeId, varId) | ||||
| } | } | ||||
| const isSysVar = nodeId === 'sys' | const isSysVar = nodeId === 'sys' | ||||
| const data = await doResetToLastRunValue(varId) | const data = await doResetToLastRunValue(varId) | ||||
| if(isSysVar) | |||||
| if (isSysVar) | |||||
| invalidateSysVarValues() | invalidateSysVarValues() | ||||
| else | else | ||||
| resetToLastRunVar(nodeId, varId, data.value) | resetToLastRunVar(nodeId, varId, data.value) |