From 570a5c72a91fab5c2ce18d796c87e98a1481f2b8 Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 16 Apr 2024 12:00:45 +0800 Subject: [PATCH] feat: support var auto rename in prompt editor (#3510) --- .../nodes/_base/components/variable/utils.ts | 80 ++++++++++++------- .../workflow/nodes/start/use-config.ts | 8 +- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/web/app/components/workflow/nodes/_base/components/variable/utils.ts b/web/app/components/workflow/nodes/_base/components/variable/utils.ts index fb12e366ff12df..969eeea976f011 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/utils.ts +++ b/web/app/components/workflow/nodes/_base/components/variable/utils.ts @@ -233,6 +233,16 @@ const matchNotSystemVars = (prompts: string[]) => { return uniqVars } +const replaceOldVarInText = (text: string, oldVar: ValueSelector, newVar: ValueSelector) => { + if (!text || typeof text !== 'string') + return text + + if (!newVar || newVar.length === 0) + return text + + return text.replaceAll(`{{#${oldVar.join('.')}#}}`, `{{#${newVar.join('.')}#}}`) +} + export const getNodeUsedVars = (node: Node): ValueSelector[] => { const { data } = node const { type } = data @@ -349,14 +359,21 @@ export const updateNodeVars = (oldNode: Node, oldVarSelector: ValueSelector, new } case BlockEnum.LLM: { const payload = data as LLMNodeType - // TODO: update in inputs - // if (payload.variables) { - // payload.variables = payload.variables.map((v) => { - // if (v.value_selector.join('.') === oldVarSelector.join('.')) - // v.value_selector = newVarSelector - // return v - // }) - // } + const isChatModel = payload.model?.mode === 'chat' + if (isChatModel) { + payload.prompt_template = (payload.prompt_template as PromptItem[]).map((prompt) => { + return { + ...prompt, + text: replaceOldVarInText(prompt.text, oldVarSelector, newVarSelector), + } + }) + } + else { + payload.prompt_template = { + ...payload.prompt_template, + text: replaceOldVarInText((payload.prompt_template as PromptItem).text, oldVarSelector, newVarSelector), + } + } if (payload.context?.variable_selector?.join('.') === oldVarSelector.join('.')) payload.context.variable_selector = newVarSelector @@ -408,30 +425,35 @@ export const updateNodeVars = (oldNode: Node, oldVarSelector: ValueSelector, new break } case BlockEnum.HttpRequest: { - // TODO: update in inputs - // const payload = data as HttpNodeType - // if (payload.variables) { - // payload.variables = payload.variables.map((v) => { - // if (v.value_selector.join('.') === oldVarSelector.join('.')) - // v.value_selector = newVarSelector - // return v - // }) - // } + const payload = data as HttpNodeType + payload.url = replaceOldVarInText(payload.url, oldVarSelector, newVarSelector) + payload.headers = replaceOldVarInText(payload.headers, oldVarSelector, newVarSelector) + payload.params = replaceOldVarInText(payload.params, oldVarSelector, newVarSelector) + payload.body.data = replaceOldVarInText(payload.body.data, oldVarSelector, newVarSelector) break } case BlockEnum.Tool: { - // TODO: update in inputs - // const payload = data as ToolNodeType - // if (payload.tool_parameters) { - // payload.tool_parameters = payload.tool_parameters.map((v) => { - // if (v.type === VarKindType.static) - // return v - - // if (v.value_selector?.join('.') === oldVarSelector.join('.')) - // v.value_selector = newVarSelector - // return v - // }) - // } + const payload = data as ToolNodeType + const hasShouldRenameVar = Object.keys(payload.tool_parameters)?.filter(key => payload.tool_parameters[key].type !== ToolVarType.constant) + if (hasShouldRenameVar) { + Object.keys(payload.tool_parameters).forEach((key) => { + const value = payload.tool_parameters[key] + const { type } = value + if (type === ToolVarType.variable) { + payload.tool_parameters[key] = { + ...value, + value: newVarSelector, + } + } + + if (type === ToolVarType.mixed) { + payload.tool_parameters[key] = { + ...value, + value: replaceOldVarInText(payload.tool_parameters[key].value as string, oldVarSelector, newVarSelector), + } + } + }) + } break } case BlockEnum.VariableAssigner: { diff --git a/web/app/components/workflow/nodes/start/use-config.ts b/web/app/components/workflow/nodes/start/use-config.ts index 8fe352554cb377..e30e8c283872c2 100644 --- a/web/app/components/workflow/nodes/start/use-config.ts +++ b/web/app/components/workflow/nodes/start/use-config.ts @@ -28,11 +28,13 @@ const useConfig = (id: string, payload: StartNodeType) => { setFalse: hideRemoveVarConfirm, }] = useBoolean(false) const [removedVar, setRemovedVar] = useState([]) + const [removedIndex, setRemoveIndex] = useState(0) const handleVarListChange = useCallback((newList: InputVar[], moreInfo?: { index: number; payload: MoreInfo }) => { if (moreInfo?.payload?.type === ChangeType.remove) { if (isVarUsedInNodes([id, moreInfo?.payload?.payload?.beforeKey || ''])) { showRemoveVarConfirm() setRemovedVar([id, moreInfo?.payload?.payload?.beforeKey || '']) + setRemoveIndex(moreInfo?.index as number) return } } @@ -48,9 +50,13 @@ const useConfig = (id: string, payload: StartNodeType) => { }, [handleOutVarRenameChange, id, inputs, isVarUsedInNodes, setInputs, showRemoveVarConfirm]) const removeVarInNode = useCallback(() => { + const newInputs = produce(inputs, (draft) => { + draft.variables.splice(removedIndex, 1) + }) + setInputs(newInputs) removeUsedVarInNodes(removedVar) hideRemoveVarConfirm() - }, [hideRemoveVarConfirm, removeUsedVarInNodes, removedVar]) + }, [hideRemoveVarConfirm, inputs, removeUsedVarInNodes, removedIndex, removedVar, setInputs]) const handleAddVariable = useCallback((payload: InputVar) => { const newInputs = produce(inputs, (draft: StartNodeType) => {