mirror of
https://github.com/langgenius/dify.git
synced 2025-07-19 07:31:09 +00:00
235 lines
8.9 KiB
TypeScript
235 lines
8.9 KiB
TypeScript
![]() |
import { fetchNodeInspectVars } from '@/service/workflow'
|
||
|
import { useStore, useWorkflowStore } from '@/app/components/workflow/store'
|
||
|
import type { ValueSelector } from '@/app/components/workflow/types'
|
||
|
import type { VarInInspect } from '@/types/workflow'
|
||
|
import { VarInInspectType } from '@/types/workflow'
|
||
|
import {
|
||
|
useDeleteAllInspectorVars,
|
||
|
useDeleteInspectVar,
|
||
|
useDeleteNodeInspectorVars,
|
||
|
useEditInspectorVar,
|
||
|
useInvalidateConversationVarValues,
|
||
|
useInvalidateSysVarValues,
|
||
|
useResetConversationVar,
|
||
|
useResetToLastRunValue,
|
||
|
} from '@/service/use-workflow'
|
||
|
import { useCallback } from 'react'
|
||
|
import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils'
|
||
|
import produce from 'immer'
|
||
|
import type { Node } from '@/app/components/workflow/types'
|
||
|
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 { useConfigsMap } from './use-configs-map'
|
||
|
|
||
|
export const useInspectVarsCrud = () => {
|
||
|
const workflowStore = useWorkflowStore()
|
||
|
const appId = useStore(s => s.appId)
|
||
|
const { conversationVarsUrl, systemVarsUrl } = useConfigsMap()
|
||
|
const invalidateConversationVarValues = useInvalidateConversationVarValues(conversationVarsUrl)
|
||
|
const { mutateAsync: doResetConversationVar } = useResetConversationVar(appId)
|
||
|
const { mutateAsync: doResetToLastRunValue } = useResetToLastRunValue(appId)
|
||
|
const invalidateSysVarValues = useInvalidateSysVarValues(systemVarsUrl)
|
||
|
|
||
|
const { mutateAsync: doDeleteAllInspectorVars } = useDeleteAllInspectorVars(appId)
|
||
|
const { mutate: doDeleteNodeInspectorVars } = useDeleteNodeInspectorVars(appId)
|
||
|
const { mutate: doDeleteInspectVar } = useDeleteInspectVar(appId)
|
||
|
|
||
|
const { mutateAsync: doEditInspectorVar } = useEditInspectorVar(appId)
|
||
|
const { handleCancelNodeSuccessStatus } = useNodesInteractionsWithoutSync()
|
||
|
const { handleEdgeCancelRunningStatus } = useEdgesInteractionsWithoutSync()
|
||
|
const getNodeInspectVars = useCallback((nodeId: string) => {
|
||
|
const { nodesWithInspectVars } = workflowStore.getState()
|
||
|
const node = nodesWithInspectVars.find(node => node.nodeId === nodeId)
|
||
|
return node
|
||
|
}, [workflowStore])
|
||
|
|
||
|
const getVarId = useCallback((nodeId: string, varName: string) => {
|
||
|
const node = getNodeInspectVars(nodeId)
|
||
|
if (!node)
|
||
|
return undefined
|
||
|
const varId = node.vars.find((varItem) => {
|
||
|
return varItem.selector[1] === varName
|
||
|
})?.id
|
||
|
return varId
|
||
|
}, [getNodeInspectVars])
|
||
|
|
||
|
const getInspectVar = useCallback((nodeId: string, name: string): VarInInspect | undefined => {
|
||
|
const node = getNodeInspectVars(nodeId)
|
||
|
if (!node)
|
||
|
return undefined
|
||
|
|
||
|
const variable = node.vars.find((varItem) => {
|
||
|
return varItem.name === name
|
||
|
})
|
||
|
return variable
|
||
|
}, [getNodeInspectVars])
|
||
|
|
||
|
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
|
||
|
}, [getInspectVar])
|
||
|
|
||
|
const hasNodeInspectVars = useCallback((nodeId: string) => {
|
||
|
return !!getNodeInspectVars(nodeId)
|
||
|
}, [getNodeInspectVars])
|
||
|
|
||
|
const fetchInspectVarValue = useCallback(async (selector: ValueSelector) => {
|
||
|
const {
|
||
|
appId,
|
||
|
setNodeInspectVars,
|
||
|
} = workflowStore.getState()
|
||
|
const nodeId = selector[0]
|
||
|
const isSystemVar = nodeId === 'sys'
|
||
|
const isConversationVar = nodeId === 'conversation'
|
||
|
if (isSystemVar) {
|
||
|
invalidateSysVarValues()
|
||
|
return
|
||
|
}
|
||
|
if (isConversationVar) {
|
||
|
invalidateConversationVarValues()
|
||
|
return
|
||
|
}
|
||
|
const vars = await fetchNodeInspectVars(appId, nodeId)
|
||
|
setNodeInspectVars(nodeId, vars)
|
||
|
}, [workflowStore, invalidateSysVarValues, invalidateConversationVarValues])
|
||
|
|
||
|
// after last run would call this
|
||
|
const appendNodeInspectVars = useCallback((nodeId: string, payload: VarInInspect[], allNodes: Node[]) => {
|
||
|
const {
|
||
|
nodesWithInspectVars,
|
||
|
setNodesWithInspectVars,
|
||
|
} = workflowStore.getState()
|
||
|
const nodes = produce(nodesWithInspectVars, (draft) => {
|
||
|
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])
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
setNodesWithInspectVars(nodes)
|
||
|
handleCancelNodeSuccessStatus(nodeId)
|
||
|
}, [workflowStore, handleCancelNodeSuccessStatus])
|
||
|
|
||
|
const hasNodeInspectVar = useCallback((nodeId: string, varId: string) => {
|
||
|
const { nodesWithInspectVars } = workflowStore.getState()
|
||
|
const targetNode = nodesWithInspectVars.find(item => item.nodeId === nodeId)
|
||
|
if(!targetNode || !targetNode.vars)
|
||
|
return false
|
||
|
return targetNode.vars.some(item => item.id === varId)
|
||
|
}, [workflowStore])
|
||
|
|
||
|
const deleteInspectVar = useCallback(async (nodeId: string, varId: string) => {
|
||
|
const { deleteInspectVar } = workflowStore.getState()
|
||
|
if(hasNodeInspectVar(nodeId, varId)) {
|
||
|
await doDeleteInspectVar(varId)
|
||
|
deleteInspectVar(nodeId, varId)
|
||
|
}
|
||
|
}, [doDeleteInspectVar, workflowStore, hasNodeInspectVar])
|
||
|
|
||
|
const resetConversationVar = useCallback(async (varId: string) => {
|
||
|
await doResetConversationVar(varId)
|
||
|
invalidateConversationVarValues()
|
||
|
}, [doResetConversationVar, invalidateConversationVarValues])
|
||
|
|
||
|
const deleteNodeInspectorVars = useCallback(async (nodeId: string) => {
|
||
|
const { deleteNodeInspectVars } = workflowStore.getState()
|
||
|
if (hasNodeInspectVars(nodeId)) {
|
||
|
await doDeleteNodeInspectorVars(nodeId)
|
||
|
deleteNodeInspectVars(nodeId)
|
||
|
}
|
||
|
}, [doDeleteNodeInspectorVars, workflowStore, hasNodeInspectVars])
|
||
|
|
||
|
const deleteAllInspectorVars = useCallback(async () => {
|
||
|
const { deleteAllInspectVars } = workflowStore.getState()
|
||
|
await doDeleteAllInspectorVars()
|
||
|
await invalidateConversationVarValues()
|
||
|
await invalidateSysVarValues()
|
||
|
deleteAllInspectVars()
|
||
|
handleEdgeCancelRunningStatus()
|
||
|
}, [doDeleteAllInspectorVars, invalidateConversationVarValues, invalidateSysVarValues, workflowStore, handleEdgeCancelRunningStatus])
|
||
|
|
||
|
const editInspectVarValue = useCallback(async (nodeId: string, varId: string, value: any) => {
|
||
|
const { setInspectVarValue } = workflowStore.getState()
|
||
|
await doEditInspectorVar({
|
||
|
varId,
|
||
|
value,
|
||
|
})
|
||
|
setInspectVarValue(nodeId, varId, value)
|
||
|
if (nodeId === VarInInspectType.conversation)
|
||
|
invalidateConversationVarValues()
|
||
|
if (nodeId === VarInInspectType.system)
|
||
|
invalidateSysVarValues()
|
||
|
}, [doEditInspectorVar, invalidateConversationVarValues, invalidateSysVarValues, workflowStore])
|
||
|
|
||
|
const renameInspectVarName = useCallback(async (nodeId: string, oldName: string, newName: string) => {
|
||
|
const { renameInspectVarName } = workflowStore.getState()
|
||
|
const varId = getVarId(nodeId, oldName)
|
||
|
if (!varId)
|
||
|
return
|
||
|
|
||
|
const newSelector = [nodeId, newName]
|
||
|
await doEditInspectorVar({
|
||
|
varId,
|
||
|
name: newName,
|
||
|
})
|
||
|
renameInspectVarName(nodeId, varId, newSelector)
|
||
|
}, [doEditInspectorVar, getVarId, workflowStore])
|
||
|
|
||
|
const isInspectVarEdited = useCallback((nodeId: string, name: string) => {
|
||
|
const inspectVar = getInspectVar(nodeId, name)
|
||
|
if (!inspectVar)
|
||
|
return false
|
||
|
|
||
|
return inspectVar.edited
|
||
|
}, [getInspectVar])
|
||
|
|
||
|
const resetToLastRunVar = useCallback(async (nodeId: string, varId: string) => {
|
||
|
const { resetToLastRunVar } = workflowStore.getState()
|
||
|
const isSysVar = nodeId === 'sys'
|
||
|
const data = await doResetToLastRunValue(varId)
|
||
|
|
||
|
if(isSysVar)
|
||
|
invalidateSysVarValues()
|
||
|
else
|
||
|
resetToLastRunVar(nodeId, varId, data.value)
|
||
|
}, [doResetToLastRunValue, invalidateSysVarValues, workflowStore])
|
||
|
|
||
|
return {
|
||
|
hasNodeInspectVars,
|
||
|
hasSetInspectVar,
|
||
|
fetchInspectVarValue,
|
||
|
editInspectVarValue,
|
||
|
renameInspectVarName,
|
||
|
appendNodeInspectVars,
|
||
|
deleteInspectVar,
|
||
|
deleteNodeInspectorVars,
|
||
|
deleteAllInspectorVars,
|
||
|
isInspectVarEdited,
|
||
|
resetToLastRunVar,
|
||
|
invalidateSysVarValues,
|
||
|
resetConversationVar,
|
||
|
invalidateConversationVarValues,
|
||
|
}
|
||
|
}
|