mirror of
https://github.com/langgenius/dify.git
synced 2026-04-14 07:56:31 +08:00
fix: can remove struct
This commit is contained in:
parent
4f3872277c
commit
66cf787755
@ -88,7 +88,7 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { hasSettedApiKey } = useProviderContext()
|
||||
const [open, setOpen] = useState(true)
|
||||
const [open, setOpen] = useState(false)
|
||||
const { data: parameterRulesData, isLoading } = useSWR((provider && modelId) ? `/workspaces/current/model-providers/${provider}/models/parameter-rules?model=${modelId}` : null, fetchModelParameterRules)
|
||||
const {
|
||||
currentProvider,
|
||||
|
||||
@ -42,7 +42,7 @@ import {
|
||||
START_INITIAL_POSITION,
|
||||
SUPPORT_OUTPUT_VARS_NODE,
|
||||
} from '../constants'
|
||||
import { findUsedVarNodes, updateNodeVars } from '../nodes/_base/components/variable/utils'
|
||||
import { findUsedVarNodes, getNodeOutputVars, updateNodeVars } from '../nodes/_base/components/variable/utils'
|
||||
import {
|
||||
useNodesExtraData,
|
||||
useNodesInitialData,
|
||||
@ -233,6 +233,35 @@ export const useWorkflow = () => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [store])
|
||||
|
||||
const isVarUsedInNodes = useCallback((nodeId: string, varSelector: ValueSelector) => {
|
||||
const afterNodes = getAfterNodesInSameBranch(nodeId)
|
||||
const effectNodes = findUsedVarNodes(varSelector, afterNodes)
|
||||
return effectNodes.length > 0
|
||||
}, [getAfterNodesInSameBranch])
|
||||
|
||||
const removeUsedVarInNodes = useCallback((nodeId: string, varSelector: ValueSelector) => {
|
||||
const { getNodes, setNodes } = store.getState()
|
||||
const afterNodes = getAfterNodesInSameBranch(nodeId)
|
||||
const effectNodes = findUsedVarNodes(varSelector, afterNodes)
|
||||
if (effectNodes.length > 0) {
|
||||
const newNodes = getNodes().map((node) => {
|
||||
if (effectNodes.find(n => n.id === node.id))
|
||||
return updateNodeVars(node, varSelector, [])
|
||||
|
||||
return node
|
||||
})
|
||||
setNodes(newNodes)
|
||||
}
|
||||
}, [getAfterNodesInSameBranch, store])
|
||||
|
||||
const isNodeVarsUsedInNodes = useCallback((node: Node, isChatMode: boolean) => {
|
||||
const outputVars = getNodeOutputVars(node, isChatMode)
|
||||
const isUsed = outputVars.some((varSelector) => {
|
||||
return isVarUsedInNodes(node.id, varSelector)
|
||||
})
|
||||
return isUsed
|
||||
}, [isVarUsedInNodes])
|
||||
|
||||
const isValidConnection = useCallback(({ source, target }: Connection) => {
|
||||
const { getNodes } = store.getState()
|
||||
const nodes = getNodes()
|
||||
@ -317,6 +346,9 @@ export const useWorkflow = () => {
|
||||
getBeforeNodesInSameBranch,
|
||||
getAfterNodesInSameBranch,
|
||||
handleOutVarRenameChange,
|
||||
isVarUsedInNodes,
|
||||
removeUsedVarInNodes,
|
||||
isNodeVarsUsedInNodes,
|
||||
isValidConnection,
|
||||
formatTimeFromNow,
|
||||
getValidTreeNodes,
|
||||
|
||||
@ -211,7 +211,7 @@ export const getVarType = (value: ValueSelector, availableNodes: any[], isChatMo
|
||||
}
|
||||
}
|
||||
|
||||
const getNodeUsedVars = (node: Node): ValueSelector[] => {
|
||||
export const getNodeUsedVars = (node: Node): ValueSelector[] => {
|
||||
const { data } = node
|
||||
const { type } = data
|
||||
let res: ValueSelector[] = []
|
||||
@ -421,3 +421,98 @@ export const updateNodeVars = (oldNode: Node, oldVarSelector: ValueSelector, new
|
||||
})
|
||||
return newNode
|
||||
}
|
||||
const varToValueSelectorList = (v: Var, parentValueSelector: ValueSelector, res: ValueSelector[]) => {
|
||||
if (!v.variable)
|
||||
return
|
||||
|
||||
res.push([...parentValueSelector, v.variable])
|
||||
|
||||
if (v.children && v.children.length > 0) {
|
||||
v.children.forEach((child) => {
|
||||
varToValueSelectorList(child, [...parentValueSelector, v.variable], res)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const varsToValueSelectorList = (vars: Var | Var[], parentValueSelector: ValueSelector, res: ValueSelector[]) => {
|
||||
if (Array.isArray(vars)) {
|
||||
vars.forEach((v) => {
|
||||
varToValueSelectorList(v, parentValueSelector, res)
|
||||
})
|
||||
}
|
||||
varToValueSelectorList(vars as Var, parentValueSelector, res)
|
||||
}
|
||||
|
||||
// const test: ValueSelector[] = []
|
||||
// varsToValueSelectorList(LLM_OUTPUT_STRUCT, ['ttt'], test)
|
||||
// console.log(test)
|
||||
|
||||
export const getNodeOutputVars = (node: Node, isChatMode: boolean): ValueSelector[] => {
|
||||
const { data, id } = node
|
||||
const { type } = data
|
||||
let res: ValueSelector[] = []
|
||||
|
||||
switch (type) {
|
||||
case BlockEnum.Start: {
|
||||
const {
|
||||
variables,
|
||||
} = data as StartNodeType
|
||||
res = variables.map((v) => {
|
||||
return [id, v.variable]
|
||||
})
|
||||
|
||||
if (isChatMode) {
|
||||
res.push([id, 'sys', 'query'])
|
||||
res.push([id, 'sys', 'files'])
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case BlockEnum.LLM: {
|
||||
varsToValueSelectorList(LLM_OUTPUT_STRUCT, [id], res)
|
||||
break
|
||||
}
|
||||
|
||||
case BlockEnum.KnowledgeRetrieval: {
|
||||
varsToValueSelectorList(KNOWLEDGE_RETRIEVAL_OUTPUT_STRUCT, [id], res)
|
||||
break
|
||||
}
|
||||
|
||||
case BlockEnum.Code: {
|
||||
const {
|
||||
outputs,
|
||||
} = data as CodeNodeType
|
||||
Object.keys(outputs).forEach((key) => {
|
||||
res.push([id, key])
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
case BlockEnum.TemplateTransform: {
|
||||
varsToValueSelectorList(TEMPLATE_TRANSFORM_OUTPUT_STRUCT, [id], res)
|
||||
break
|
||||
}
|
||||
|
||||
case BlockEnum.QuestionClassifier: {
|
||||
varsToValueSelectorList(isChatMode ? CHAT_QUESTION_CLASSIFIER_OUTPUT_STRUCT : COMPLETION_QUESTION_CLASSIFIER_OUTPUT_STRUCT, [id], res)
|
||||
break
|
||||
}
|
||||
|
||||
case BlockEnum.HttpRequest: {
|
||||
varsToValueSelectorList(HTTP_REQUEST_OUTPUT_STRUCT, [id], res)
|
||||
break
|
||||
}
|
||||
|
||||
case BlockEnum.VariableAssigner: {
|
||||
res.push([id, 'output'])
|
||||
break
|
||||
}
|
||||
|
||||
case BlockEnum.Tool: {
|
||||
varsToValueSelectorList(TOOL_OUTPUT_STRUCT, [id], res)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import React, { useCallback } from 'react'
|
||||
import produce from 'immer'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import VarItem from './var-item'
|
||||
import type { InputVar, MoreInfo } from '@/app/components/workflow/types'
|
||||
import { ChangeType, type InputVar, type MoreInfo } from '@/app/components/workflow/types'
|
||||
type Props = {
|
||||
readonly: boolean
|
||||
list: InputVar[]
|
||||
@ -32,7 +32,15 @@ const VarList: FC<Props> = ({
|
||||
const newList = produce(list, (draft) => {
|
||||
draft.splice(index, 1)
|
||||
})
|
||||
onChange(newList)
|
||||
onChange(newList, {
|
||||
index,
|
||||
payload: {
|
||||
type: ChangeType.remove,
|
||||
payload: {
|
||||
beforeKey: list[index].variable,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}, [list, onChange])
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import { useCallback } from 'react'
|
||||
import produce from 'immer'
|
||||
import { useBoolean } from 'ahooks'
|
||||
import type { StartNodeType } from './types'
|
||||
import type { InputVar, MoreInfo } from '@/app/components/workflow/types'
|
||||
import { ChangeType, type InputVar, type MoreInfo } from '@/app/components/workflow/types'
|
||||
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
|
||||
import {
|
||||
useIsChatMode,
|
||||
@ -12,7 +12,7 @@ import {
|
||||
|
||||
const useConfig = (id: string, payload: StartNodeType) => {
|
||||
const { nodesReadOnly: readOnly } = useNodesReadOnly()
|
||||
const { handleOutVarRenameChange } = useWorkflow()
|
||||
const { handleOutVarRenameChange, removeUsedVarInNodes } = useWorkflow()
|
||||
const isChatMode = useIsChatMode()
|
||||
|
||||
const { inputs, setInputs } = useNodeCrud<StartNodeType>(id, payload)
|
||||
@ -27,10 +27,12 @@ const useConfig = (id: string, payload: StartNodeType) => {
|
||||
draft.variables = newList
|
||||
})
|
||||
setInputs(newInputs)
|
||||
if (moreInfo) {
|
||||
if (moreInfo?.payload?.type === ChangeType.changeVarName) {
|
||||
const changedVar = newList[moreInfo.index]
|
||||
handleOutVarRenameChange(id, [id, inputs.variables[moreInfo.index].variable], [id, changedVar.variable])
|
||||
}
|
||||
if (moreInfo?.payload?.type === ChangeType.remove)
|
||||
removeUsedVarInNodes(id, [id, moreInfo?.payload?.payload?.beforeKey || ''])
|
||||
}, [handleOutVarRenameChange, id, inputs, setInputs])
|
||||
|
||||
const handleAddVariable = useCallback((payload: InputVar) => {
|
||||
|
||||
@ -255,13 +255,14 @@ export type HistoryWorkflowData = {
|
||||
|
||||
export enum ChangeType {
|
||||
changeVarName = 'changeVarName',
|
||||
remove = 'remove',
|
||||
}
|
||||
|
||||
export type MoreInfo = {
|
||||
type: ChangeType
|
||||
payload?: {
|
||||
beforeKey: string
|
||||
afterKey: string
|
||||
afterKey?: string
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user