Chore/workflow last run (#21823)
Co-authored-by: Joel <iamjoel007@gmail.com>
This commit is contained in:
@@ -7,6 +7,12 @@ import {
|
||||
} from 'zustand'
|
||||
import { createStore } from 'zustand/vanilla'
|
||||
import { HooksStoreContext } from './provider'
|
||||
import type { IOtherOptions } from '@/service/base'
|
||||
import type { VarInInspect } from '@/types/workflow'
|
||||
import type {
|
||||
Node,
|
||||
ValueSelector,
|
||||
} from '@/app/components/workflow/types'
|
||||
|
||||
type CommonHooksFnMap = {
|
||||
doSyncWorkflowDraft: (
|
||||
@@ -22,11 +28,30 @@ type CommonHooksFnMap = {
|
||||
handleBackupDraft: () => void
|
||||
handleLoadBackupDraft: () => void
|
||||
handleRestoreFromPublishedWorkflow: (...args: any[]) => void
|
||||
handleRun: (...args: any[]) => void
|
||||
handleRun: (params: any, callback?: IOtherOptions,) => void
|
||||
handleStopRun: (...args: any[]) => void
|
||||
handleStartWorkflowRun: () => void
|
||||
handleWorkflowStartRunInWorkflow: () => void
|
||||
handleWorkflowStartRunInChatflow: () => void
|
||||
fetchInspectVars: () => Promise<void>
|
||||
hasNodeInspectVars: (nodeId: string) => boolean
|
||||
hasSetInspectVar: (nodeId: string, name: string, sysVars: VarInInspect[], conversationVars: VarInInspect[]) => boolean
|
||||
fetchInspectVarValue: (selector: ValueSelector) => Promise<void>
|
||||
editInspectVarValue: (nodeId: string, varId: string, value: any) => Promise<void>
|
||||
renameInspectVarName: (nodeId: string, oldName: string, newName: string) => Promise<void>
|
||||
appendNodeInspectVars: (nodeId: string, payload: VarInInspect[], allNodes: Node[]) => void
|
||||
deleteInspectVar: (nodeId: string, varId: string) => Promise<void>
|
||||
deleteNodeInspectorVars: (nodeId: string) => Promise<void>
|
||||
deleteAllInspectorVars: () => Promise<void>
|
||||
isInspectVarEdited: (nodeId: string, name: string) => boolean
|
||||
resetToLastRunVar: (nodeId: string, varId: string) => Promise<void>
|
||||
invalidateSysVarValues: () => void
|
||||
resetConversationVar: (varId: string) => Promise<void>
|
||||
invalidateConversationVarValues: () => void
|
||||
configsMap?: {
|
||||
conversationVarsUrl: string
|
||||
systemVarsUrl: string
|
||||
}
|
||||
}
|
||||
|
||||
export type Shape = {
|
||||
@@ -45,6 +70,21 @@ export const createHooksStore = ({
|
||||
handleStartWorkflowRun = noop,
|
||||
handleWorkflowStartRunInWorkflow = noop,
|
||||
handleWorkflowStartRunInChatflow = noop,
|
||||
fetchInspectVars = async () => noop(),
|
||||
hasNodeInspectVars = () => false,
|
||||
hasSetInspectVar = () => false,
|
||||
fetchInspectVarValue = async () => noop(),
|
||||
editInspectVarValue = async () => noop(),
|
||||
renameInspectVarName = async () => noop(),
|
||||
appendNodeInspectVars = () => noop(),
|
||||
deleteInspectVar = async () => noop(),
|
||||
deleteNodeInspectorVars = async () => noop(),
|
||||
deleteAllInspectorVars = async () => noop(),
|
||||
isInspectVarEdited = () => false,
|
||||
resetToLastRunVar = async () => noop(),
|
||||
invalidateSysVarValues = noop,
|
||||
resetConversationVar = async () => noop(),
|
||||
invalidateConversationVarValues = noop,
|
||||
}: Partial<Shape>) => {
|
||||
return createStore<Shape>(set => ({
|
||||
refreshAll: props => set(state => ({ ...state, ...props })),
|
||||
@@ -59,6 +99,21 @@ export const createHooksStore = ({
|
||||
handleStartWorkflowRun,
|
||||
handleWorkflowStartRunInWorkflow,
|
||||
handleWorkflowStartRunInChatflow,
|
||||
fetchInspectVars,
|
||||
hasNodeInspectVars,
|
||||
hasSetInspectVar,
|
||||
fetchInspectVarValue,
|
||||
editInspectVarValue,
|
||||
renameInspectVarName,
|
||||
appendNodeInspectVars,
|
||||
deleteInspectVar,
|
||||
deleteNodeInspectorVars,
|
||||
deleteAllInspectorVars,
|
||||
isInspectVarEdited,
|
||||
resetToLastRunVar,
|
||||
invalidateSysVarValues,
|
||||
resetConversationVar,
|
||||
invalidateConversationVarValues,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@@ -17,3 +17,5 @@ export * from './use-workflow-interactions'
|
||||
export * from './use-workflow-mode'
|
||||
export * from './use-format-time-from-now'
|
||||
export * from './use-workflow-refresh-draft'
|
||||
export * from './use-inspect-vars-crud'
|
||||
export * from './use-set-workflow-vars-with-value'
|
||||
|
@@ -1,217 +1,29 @@
|
||||
import { fetchNodeInspectVars } from '@/service/workflow'
|
||||
import { useStore, useWorkflowStore } from '../store'
|
||||
import type { ValueSelector } from '../types'
|
||||
import type { VarInInspect } from '@/types/workflow'
|
||||
import { VarInInspectType } from '@/types/workflow'
|
||||
import { useStore } from '../store'
|
||||
import { useHooksStore } from '@/app/components/workflow/hooks-store'
|
||||
import {
|
||||
useConversationVarValues,
|
||||
useDeleteAllInspectorVars,
|
||||
useDeleteInspectVar,
|
||||
useDeleteNodeInspectorVars,
|
||||
useEditInspectorVar,
|
||||
useInvalidateConversationVarValues,
|
||||
useInvalidateSysVarValues,
|
||||
useResetConversationVar,
|
||||
useResetToLastRunValue,
|
||||
useSysVarValues,
|
||||
} from '@/service/use-workflow'
|
||||
import { useCallback } from 'react'
|
||||
import { isConversationVar, isENV, isSystemVar } from '../nodes/_base/components/variable/utils'
|
||||
import produce from 'immer'
|
||||
import type { Node } from '@/app/components/workflow/types'
|
||||
import { useNodesInteractionsWithoutSync } from './use-nodes-interactions-without-sync'
|
||||
import { useEdgesInteractionsWithoutSync } from './use-edges-interactions-without-sync'
|
||||
|
||||
const useInspectVarsCrud = () => {
|
||||
const workflowStore = useWorkflowStore()
|
||||
const nodesWithInspectVars = useStore(s => s.nodesWithInspectVars)
|
||||
const {
|
||||
appId,
|
||||
setNodeInspectVars,
|
||||
setInspectVarValue,
|
||||
renameInspectVarName: renameInspectVarNameInStore,
|
||||
deleteAllInspectVars: deleteAllInspectVarsInStore,
|
||||
deleteNodeInspectVars: deleteNodeInspectVarsInStore,
|
||||
deleteInspectVar: deleteInspectVarInStore,
|
||||
setNodesWithInspectVars,
|
||||
resetToLastRunVar: resetToLastRunVarInStore,
|
||||
} = workflowStore.getState()
|
||||
|
||||
const { data: conversationVars } = useConversationVarValues(appId)
|
||||
const invalidateConversationVarValues = useInvalidateConversationVarValues(appId)
|
||||
const { mutateAsync: doResetConversationVar } = useResetConversationVar(appId)
|
||||
const { mutateAsync: doResetToLastRunValue } = useResetToLastRunValue(appId)
|
||||
const { data: systemVars } = useSysVarValues(appId)
|
||||
const invalidateSysVarValues = useInvalidateSysVarValues(appId)
|
||||
|
||||
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 node = nodesWithInspectVars.find(node => node.nodeId === nodeId)
|
||||
return node
|
||||
}, [nodesWithInspectVars])
|
||||
|
||||
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 = async (selector: ValueSelector) => {
|
||||
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)
|
||||
}
|
||||
|
||||
// after last run would call this
|
||||
const appendNodeInspectVars = (nodeId: string, payload: VarInInspect[], allNodes: Node[]) => {
|
||||
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 top
|
||||
draft.unshift(draft.splice(index, 1)[0])
|
||||
}
|
||||
}
|
||||
})
|
||||
setNodesWithInspectVars(nodes)
|
||||
handleCancelNodeSuccessStatus(nodeId)
|
||||
}
|
||||
|
||||
const hasNodeInspectVar = (nodeId: string, varId: string) => {
|
||||
const targetNode = nodesWithInspectVars.find(item => item.nodeId === nodeId)
|
||||
if(!targetNode || !targetNode.vars)
|
||||
return false
|
||||
return targetNode.vars.some(item => item.id === varId)
|
||||
}
|
||||
|
||||
const deleteInspectVar = async (nodeId: string, varId: string) => {
|
||||
if(hasNodeInspectVar(nodeId, varId)) {
|
||||
await doDeleteInspectVar(varId)
|
||||
deleteInspectVarInStore(nodeId, varId)
|
||||
}
|
||||
}
|
||||
|
||||
const resetConversationVar = async (varId: string) => {
|
||||
await doResetConversationVar(varId)
|
||||
invalidateConversationVarValues()
|
||||
}
|
||||
|
||||
const deleteNodeInspectorVars = async (nodeId: string) => {
|
||||
if (hasNodeInspectVars(nodeId)) {
|
||||
await doDeleteNodeInspectorVars(nodeId)
|
||||
deleteNodeInspectVarsInStore(nodeId)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteAllInspectorVars = async () => {
|
||||
await doDeleteAllInspectorVars()
|
||||
await invalidateConversationVarValues()
|
||||
await invalidateSysVarValues()
|
||||
deleteAllInspectVarsInStore()
|
||||
handleEdgeCancelRunningStatus()
|
||||
}
|
||||
|
||||
const editInspectVarValue = useCallback(async (nodeId: string, varId: string, value: any) => {
|
||||
await doEditInspectorVar({
|
||||
varId,
|
||||
value,
|
||||
})
|
||||
setInspectVarValue(nodeId, varId, value)
|
||||
if (nodeId === VarInInspectType.conversation)
|
||||
invalidateConversationVarValues()
|
||||
if (nodeId === VarInInspectType.system)
|
||||
invalidateSysVarValues()
|
||||
}, [doEditInspectorVar, invalidateConversationVarValues, invalidateSysVarValues, setInspectVarValue])
|
||||
|
||||
const renameInspectVarName = async (nodeId: string, oldName: string, newName: string) => {
|
||||
const varId = getVarId(nodeId, oldName)
|
||||
if (!varId)
|
||||
return
|
||||
|
||||
const newSelector = [nodeId, newName]
|
||||
await doEditInspectorVar({
|
||||
varId,
|
||||
name: newName,
|
||||
})
|
||||
renameInspectVarNameInStore(nodeId, varId, newSelector)
|
||||
}
|
||||
|
||||
const isInspectVarEdited = useCallback((nodeId: string, name: string) => {
|
||||
const inspectVar = getInspectVar(nodeId, name)
|
||||
if (!inspectVar)
|
||||
return false
|
||||
|
||||
return inspectVar.edited
|
||||
}, [getInspectVar])
|
||||
|
||||
const resetToLastRunVar = async (nodeId: string, varId: string) => {
|
||||
const isSysVar = nodeId === 'sys'
|
||||
const data = await doResetToLastRunValue(varId)
|
||||
|
||||
if(isSysVar)
|
||||
invalidateSysVarValues()
|
||||
else
|
||||
resetToLastRunVarInStore(nodeId, varId, data.value)
|
||||
}
|
||||
const configsMap = useHooksStore(s => s.configsMap)
|
||||
const { data: conversationVars } = useConversationVarValues(configsMap?.conversationVarsUrl)
|
||||
const { data: systemVars } = useSysVarValues(configsMap?.systemVarsUrl)
|
||||
const hasNodeInspectVars = useHooksStore(s => s.hasNodeInspectVars)
|
||||
const hasSetInspectVar = useHooksStore(s => s.hasSetInspectVar)
|
||||
const fetchInspectVarValue = useHooksStore(s => s.fetchInspectVarValue)
|
||||
const editInspectVarValue = useHooksStore(s => s.editInspectVarValue)
|
||||
const renameInspectVarName = useHooksStore(s => s.renameInspectVarName)
|
||||
const appendNodeInspectVars = useHooksStore(s => s.appendNodeInspectVars)
|
||||
const deleteInspectVar = useHooksStore(s => s.deleteInspectVar)
|
||||
const deleteNodeInspectorVars = useHooksStore(s => s.deleteNodeInspectorVars)
|
||||
const deleteAllInspectorVars = useHooksStore(s => s.deleteAllInspectorVars)
|
||||
const isInspectVarEdited = useHooksStore(s => s.isInspectVarEdited)
|
||||
const resetToLastRunVar = useHooksStore(s => s.resetToLastRunVar)
|
||||
const invalidateSysVarValues = useHooksStore(s => s.invalidateSysVarValues)
|
||||
const resetConversationVar = useHooksStore(s => s.resetConversationVar)
|
||||
const invalidateConversationVarValues = useHooksStore(s => s.invalidateConversationVarValues)
|
||||
|
||||
return {
|
||||
conversationVars: conversationVars || [],
|
||||
|
@@ -0,0 +1,9 @@
|
||||
import { useHooksStore } from '@/app/components/workflow/hooks-store'
|
||||
|
||||
export const useSetWorkflowVarsWithValue = () => {
|
||||
const fetchInspectVars = useHooksStore(s => s.fetchInspectVars)
|
||||
|
||||
return {
|
||||
fetchInspectVars,
|
||||
}
|
||||
}
|
@@ -42,6 +42,7 @@ import {
|
||||
useNodesSyncDraft,
|
||||
usePanelInteractions,
|
||||
useSelectionInteractions,
|
||||
useSetWorkflowVarsWithValue,
|
||||
useShortcuts,
|
||||
useWorkflow,
|
||||
useWorkflowReadOnly,
|
||||
@@ -82,7 +83,6 @@ import Confirm from '@/app/components/base/confirm'
|
||||
import DatasetsDetailProvider from './datasets-detail-store/provider'
|
||||
import { HooksStoreContextProvider } from './hooks-store'
|
||||
import type { Shape as HooksStoreShape } from './hooks-store'
|
||||
import useSetWorkflowVarsWithValue from '../workflow-app/hooks/use-fetch-workflow-inspect-vars'
|
||||
|
||||
const nodeTypes = {
|
||||
[CUSTOM_NODE]: CustomNode,
|
||||
|
@@ -8,7 +8,10 @@ import {
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { produce, setAutoFreeze } from 'immer'
|
||||
import { uniqBy } from 'lodash-es'
|
||||
import { useWorkflowRun } from '../../hooks'
|
||||
import {
|
||||
useSetWorkflowVarsWithValue,
|
||||
useWorkflowRun,
|
||||
} from '../../hooks'
|
||||
import { NodeRunningStatus, WorkflowRunningStatus } from '../../types'
|
||||
import { useWorkflowStore } from '../../store'
|
||||
import { DEFAULT_ITER_TIMES, DEFAULT_LOOP_TIMES } from '../../constants'
|
||||
@@ -32,7 +35,6 @@ import type { FileEntity } from '@/app/components/base/file-uploader/types'
|
||||
import { getThreadMessages } from '@/app/components/base/chat/utils'
|
||||
import { useInvalidAllLastRun } from '@/service/use-workflow'
|
||||
import { useParams } from 'next/navigation'
|
||||
import useSetWorkflowVarsWithValue from '@/app/components/workflow-app/hooks/use-fetch-workflow-inspect-vars'
|
||||
|
||||
type GetAbortController = (abortController: AbortController) => void
|
||||
type SendCallback = {
|
||||
@@ -499,7 +501,7 @@ export const useChat = (
|
||||
},
|
||||
},
|
||||
)
|
||||
}, [threadMessages, chatTree.length, updateCurrentQAOnTree, handleResponding, formSettings?.inputsForm, handleRun, notify, t, config?.suggested_questions_after_answer?.enabled])
|
||||
}, [threadMessages, chatTree.length, updateCurrentQAOnTree, handleResponding, formSettings?.inputsForm, handleRun, notify, t, config?.suggested_questions_after_answer?.enabled, fetchInspectVars, invalidAllLastRun])
|
||||
|
||||
return {
|
||||
conversationId: conversationId.current,
|
||||
|
Reference in New Issue
Block a user