From 1c4c1b5cb1eb287b7c7a6bd83e04634781d90cac Mon Sep 17 00:00:00 2001 From: twwu Date: Thu, 25 Dec 2025 10:50:20 +0800 Subject: [PATCH] refactor: streamline HITL input components by consolidating props and enhancing variable handling --- .../components/base/prompt-editor/index.tsx | 11 +- .../plugins/hitl-input-block/component-ui.tsx | 67 +++++--- .../plugins/hitl-input-block/component.tsx | 31 +++- .../hitl-input-block-replacement-block.tsx | 35 +++-- .../plugins/hitl-input-block/index.tsx | 17 +- .../plugins/hitl-input-block/node.tsx | 93 +++++++++-- .../hitl-input-block/variable-block.tsx | 145 ++++++++++++++++++ ...kflow-variable-block-replacement-block.tsx | 2 +- .../components/base/prompt-editor/types.ts | 6 +- .../human-input/components/form-content.tsx | 45 +++--- .../workflow/nodes/human-input/panel.tsx | 1 - 11 files changed, 357 insertions(+), 96 deletions(-) create mode 100644 web/app/components/base/prompt-editor/plugins/hitl-input-block/variable-block.tsx diff --git a/web/app/components/base/prompt-editor/index.tsx b/web/app/components/base/prompt-editor/index.tsx index 42ee3a0915..5670e19096 100644 --- a/web/app/components/base/prompt-editor/index.tsx +++ b/web/app/components/base/prompt-editor/index.tsx @@ -304,15 +304,8 @@ const PromptEditor: FC = ({ { hitlInputBlock?.show && ( <> - - + + ) } diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/component-ui.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/component-ui.tsx index 407c16cd65..edeec24321 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/component-ui.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/component-ui.tsx @@ -1,45 +1,56 @@ 'use client' import type { FC } from 'react' -import React, { useCallback, useEffect, useRef } from 'react' +import React, { useCallback, useEffect, useMemo, useRef } from 'react' import { VariableX } from '../../../icons/src/vender/workflow' -import { VarBlockIcon } from '@/app/components/workflow/block-icon' -import { BlockEnum, InputVarType } from '@/app/components/workflow/types' -import { Variable02 } from '../../../icons/src/vender/solid/development' +import { InputVarType } from '@/app/components/workflow/types' import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/types' import ActionButton from '../../../action-button' import { RiDeleteBinLine, RiEditLine } from '@remixicon/react' import InputField from './input-field' import { useBoolean } from 'ahooks' import Modal from '../../../modal' +import type { WorkflowNodesMap } from '../workflow-variable-block/node' +import type { ValueSelector, Var } from '@/app/components/workflow/types' +import type { Type } from '@/app/components/workflow/nodes/llm/types' +import VariableBlock from './variable-block' -type Props = { +type HITLInputComponentUIProps = { nodeId: string - nodeTitle: string varName: string - isSelected: boolean formInput?: FormInputItem onChange: (input: FormInputItem) => void onRename: (payload: FormInputItem, oldName: string) => void onRemove: (varName: string) => void + workflowNodesMap: WorkflowNodesMap + environmentVariables?: Var[] + conversationVariables?: Var[] + ragVariables?: Var[] + getVarType?: (payload: { + nodeId: string, + valueSelector: ValueSelector, + }) => Type } -const ComponentUI: FC = ({ +const HITLInputComponentUI: FC = ({ nodeId, - nodeTitle, varName, - // isSelected, formInput = { - type: InputVarType.textInput, + type: InputVarType.paragraph, output_variable_name: varName, placeholder: { type: 'constant', selector: [], value: '', }, - } as FormInputItem, + }, onChange, onRename, onRemove, + workflowNodesMap = {}, + getVarType, + environmentVariables, + conversationVariables, + ragVariables, }) => { const [isShowEditModal, { setTrue: showEditModal, @@ -79,6 +90,10 @@ const ComponentUI: FC = ({ hideEditModal() }, [hideEditModal, onChange, onRename, varName]) + const isPlaceholderVariable = useMemo(() => { + return formInput.placeholder.type === 'variable' + }, [formInput.placeholder.type]) + return (
= ({
- {/* Node info */} -
-
- -
{nodeTitle}
-
-
/
-
- -
{varName}
-
-
+ {/* Placeholder Info */} + {isPlaceholderVariable && ( + + )} + {!isPlaceholderVariable && ( +
{formInput.placeholder.value}
+ )} {/* Actions */}
@@ -141,4 +158,4 @@ const ComponentUI: FC = ({ ) } -export default React.memo(ComponentUI) +export default React.memo(HITLInputComponentUI) diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/component.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/component.tsx index 0994e27225..8cf03fa256 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/component.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/component.tsx @@ -4,29 +4,43 @@ import { DELETE_HITL_INPUT_BLOCK_COMMAND } from './' import ComponentUi from './component-ui' import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/types' import { produce } from 'immer' +import type { WorkflowNodesMap } from '../workflow-variable-block/node' +import type { ValueSelector, Var } from '@/app/components/workflow/types' +import type { Type } from '@/app/components/workflow/nodes/llm/types' -type Props = { +type HITLInputComponentProps = { nodeKey: string nodeId: string - nodeTitle: string varName: string formInputs?: FormInputItem[] onChange: (inputs: FormInputItem[]) => void onRename: (payload: FormInputItem, oldName: string) => void onRemove: (varName: string) => void + workflowNodesMap: WorkflowNodesMap + environmentVariables?: Var[] + conversationVariables?: Var[] + ragVariables?: Var[] + getVarType?: (payload: { + nodeId: string, + valueSelector: ValueSelector, + }) => Type } -const HITLInputComponent: FC = ({ +const HITLInputComponent: FC = ({ nodeKey, nodeId, - nodeTitle, varName, formInputs = [], onChange, onRename, onRemove, + workflowNodesMap = {}, + getVarType, + environmentVariables, + conversationVariables, + ragVariables, }) => { - const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_HITL_INPUT_BLOCK_COMMAND) + const [ref] = useSelectOrDelete(nodeKey, DELETE_HITL_INPUT_BLOCK_COMMAND) const payload = formInputs.find(item => item.output_variable_name === varName) const handleChange = useCallback((newPayload: FormInputItem) => { @@ -50,13 +64,16 @@ const HITLInputComponent: FC = ({ >
) diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/hitl-input-block-replacement-block.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/hitl-input-block-replacement-block.tsx index c8b30fae60..e2e6184ec2 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/hitl-input-block-replacement-block.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/hitl-input-block-replacement-block.tsx @@ -2,6 +2,7 @@ import { memo, useCallback, useEffect, + useMemo, } from 'react' import type { TextNode } from 'lexical' import { $applyNodeReplacement } from 'lexical' @@ -9,43 +10,55 @@ import { mergeRegister } from '@lexical/utils' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { decoratorTransform } from '../../utils' import type { HITLInputBlockType } from '../../types' -import { $createHITLInputNode } from './node' -import { - QueryBlockNode, -} from '../query-block/node' +import { $createHITLInputNode, HITLInputNode } from './node' import { CustomTextNode } from '../custom-text/node' import { HITL_INPUT_REG } from '@/config' const REGEX = new RegExp(HITL_INPUT_REG) const HITLInputReplacementBlock = ({ - // onInsert, nodeId, - nodeTitle, formInputs, onFormInputsChange, onFormInputItemRename, onFormInputItemRemove, + workflowNodesMap, + getVarType, + variables, }: HITLInputBlockType) => { const [editor] = useLexicalComposerContext() + const environmentVariables = useMemo(() => variables?.find(o => o.nodeId === 'env')?.vars || [], [variables]) + const conversationVariables = useMemo(() => variables?.find(o => o.nodeId === 'conversation')?.vars || [], [variables]) + const ragVariables = useMemo(() => variables?.reduce((acc, curr) => { + if (curr.nodeId === 'rag') + acc.push(...curr.vars) + else + acc.push(...curr.vars.filter(v => v.isRagVariable)) + return acc + }, []), [variables]) + useEffect(() => { - if (!editor.hasNodes([QueryBlockNode])) - throw new Error('QueryBlockNodePlugin: QueryBlockNode not registered on editor') + if (!editor.hasNodes([HITLInputNode])) + throw new Error('HITLInputNodePlugin: HITLInputNode not registered on editor') }, [editor]) - const createHITLInputBlockNode = useCallback((textNode: TextNode): QueryBlockNode => { + const createHITLInputBlockNode = useCallback((textNode: TextNode): HITLInputNode => { const varName = textNode.getTextContent().split('.')[1].replace(/#}}$/, '') return $applyNodeReplacement($createHITLInputNode( varName, nodeId, - nodeTitle, formInputs || [], onFormInputsChange!, onFormInputItemRename, onFormInputItemRemove!, + workflowNodesMap, + getVarType, + environmentVariables, + conversationVariables, + ragVariables, )) - }, [nodeId, nodeTitle, formInputs, onFormInputsChange, onFormInputItemRename, onFormInputItemRemove]) + }, [nodeId, formInputs, onFormInputsChange, onFormInputItemRename, onFormInputItemRemove, workflowNodesMap, getVarType, environmentVariables, conversationVariables, ragVariables]) const getMatch = useCallback((text: string) => { const matchArr = REGEX.exec(text) diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/index.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/index.tsx index 1c59e4520b..efaacf796f 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/index.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/index.tsx @@ -8,7 +8,7 @@ import { createCommand, } from 'lexical' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' -import type { QueryBlockType } from '../../types' +import type { HITLInputBlockType } from '../../types' import type { HITLNodeProps, } from './node' @@ -20,6 +20,7 @@ import { mergeRegister } from '@lexical/utils' export const INSERT_HITL_INPUT_BLOCK_COMMAND = createCommand('INSERT_HITL_INPUT_BLOCK_COMMAND') export const DELETE_HITL_INPUT_BLOCK_COMMAND = createCommand('DELETE_HITL_INPUT_BLOCK_COMMAND') +export const UPDATE_WORKFLOW_NODES_MAP = createCommand('UPDATE_WORKFLOW_NODES_MAP') export type HITLInputProps = { onInsert?: () => void @@ -28,9 +29,17 @@ export type HITLInputProps = { const HITLInputBlock = memo(({ onInsert, onDelete, -}: QueryBlockType) => { + workflowNodesMap, + getVarType, +}: HITLInputBlockType) => { const [editor] = useLexicalComposerContext() + useEffect(() => { + editor.update(() => { + editor.dispatchCommand(UPDATE_WORKFLOW_NODES_MAP, workflowNodesMap) + }) + }, [editor, workflowNodesMap]) + useEffect(() => { if (!editor.hasNodes([HITLInputNode])) throw new Error('HITLInputBlockPlugin: HITLInputBlock not registered on editor') @@ -41,7 +50,6 @@ const HITLInputBlock = memo(({ const { variableName, nodeId, - nodeTitle, formInputs, onFormInputsChange, onFormInputItemRename, @@ -50,11 +58,12 @@ const HITLInputBlock = memo(({ const currentHITLNode = $createHITLInputNode( variableName, nodeId, - nodeTitle, formInputs, onFormInputsChange, onFormInputItemRename, onFormInputItemRemove, + workflowNodesMap, + getVarType, ) $insertNodes([currentHITLNode]) diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/node.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/node.tsx index 491b5b74f2..8248f37967 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/node.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/node.tsx @@ -2,15 +2,22 @@ import type { LexicalNode, NodeKey, SerializedLexicalNode } from 'lexical' import { DecoratorNode } from 'lexical' import HILTInputBlockComponent from './component' import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/types' +import type { WorkflowNodesMap } from '../workflow-variable-block/node' +import type { GetVarType } from '../../types' +import type { Var } from '@/app/components/workflow/types' export type HITLNodeProps = { variableName: string nodeId: string - nodeTitle: string formInputs: FormInputItem[] onFormInputsChange: (inputs: FormInputItem[]) => void onFormInputItemRename: (payload: FormInputItem, oldName: string) => void onFormInputItemRemove: (varName: string) => void + workflowNodesMap: WorkflowNodesMap + getVarType?: GetVarType + environmentVariables?: Var[] + conversationVariables?: Var[] + ragVariables?: Var[] } export type SerializedNode = SerializedLexicalNode & HITLNodeProps @@ -18,11 +25,15 @@ export type SerializedNode = SerializedLexicalNode & HITLNodeProps export class HITLInputNode extends DecoratorNode { __variableName: string __nodeId: string - __nodeTitle: string __formInputs?: FormInputItem[] __onFormInputsChange: (inputs: FormInputItem[]) => void __onFormInputItemRename: (payload: FormInputItem, oldName: string) => void __onFormInputItemRemove: (varName: string) => void + __workflowNodesMap: WorkflowNodesMap + __getVarType?: GetVarType + __environmentVariables?: Var[] + __conversationVariables?: Var[] + __ragVariables?: Var[] isIsolated(): boolean { return true // This is necessary for drag-and-drop to work correctly @@ -41,11 +52,6 @@ export class HITLInputNode extends DecoratorNode { return self.__variableName } - getNodeTitle(): string { - const self = this.getLatest() - return self.__nodeTitle - } - getNodeId(): string { const self = this.getLatest() return self.__nodeId @@ -71,15 +77,44 @@ export class HITLInputNode extends DecoratorNode { return self.__onFormInputItemRemove } + getWorkflowNodesMap(): WorkflowNodesMap { + const self = this.getLatest() + return self.__workflowNodesMap + } + + getGetVarType(): GetVarType | undefined { + const self = this.getLatest() + return self.__getVarType + } + + getEnvironmentVariables(): Var[] { + const self = this.getLatest() + return self.__environmentVariables || [] + } + + getConversationVariables(): Var[] { + const self = this.getLatest() + return self.__conversationVariables || [] + } + + getRagVariables(): Var[] { + const self = this.getLatest() + return self.__ragVariables || [] + } + static clone(node: HITLInputNode): HITLInputNode { return new HITLInputNode( node.__variableName, node.__nodeId, - node.__nodeTitle, node.__formInputs || [], node.__onFormInputsChange, node.__onFormInputItemRename, node.__onFormInputItemRemove, + node.__workflowNodesMap, + node.__getVarType, + node.__environmentVariables, + node.__conversationVariables, + node.__ragVariables, node.__key, ) } @@ -91,22 +126,30 @@ export class HITLInputNode extends DecoratorNode { constructor( varName: string, nodeId: string, - nodeTitle: string, formInputs: FormInputItem[], onFormInputsChange: (inputs: FormInputItem[]) => void, onFormInputItemRename: (payload: FormInputItem, oldName: string) => void, onFormInputItemRemove: (varName: string) => void, + workflowNodesMap: WorkflowNodesMap, + getVarType?: GetVarType, + environmentVariables?: Var[], + conversationVariables?: Var[], + ragVariables?: Var[], key?: NodeKey, ) { super(key) this.__variableName = varName this.__nodeId = nodeId - this.__nodeTitle = nodeTitle this.__formInputs = formInputs this.__onFormInputsChange = onFormInputsChange this.__onFormInputItemRename = onFormInputItemRename this.__onFormInputItemRemove = onFormInputItemRemove + this.__workflowNodesMap = workflowNodesMap + this.__getVarType = getVarType + this.__environmentVariables = environmentVariables + this.__conversationVariables = conversationVariables + this.__ragVariables = ragVariables } createDOM(): HTMLElement { @@ -124,11 +167,15 @@ export class HITLInputNode extends DecoratorNode { nodeKey={this.getKey()} varName={this.getVariableName()} nodeId={this.getNodeId()} - nodeTitle={this.getNodeTitle()} formInputs={this.getFormInputs()} onChange={this.getOnFormInputsChange()} onRename={this.getOnFormInputItemRename()} onRemove={this.getOnFormInputItemRemove()} + workflowNodesMap={this.getWorkflowNodesMap()} + getVarType={this.getGetVarType()} + environmentVariables={this.getEnvironmentVariables()} + conversationVariables={this.getConversationVariables()} + ragVariables={this.getRagVariables()} /> } @@ -136,11 +183,15 @@ export class HITLInputNode extends DecoratorNode { const node = $createHITLInputNode( serializedNode.variableName, serializedNode.nodeId, - serializedNode.nodeTitle, serializedNode.formInputs, serializedNode.onFormInputsChange, serializedNode.onFormInputItemRename, serializedNode.onFormInputItemRemove, + serializedNode.workflowNodesMap, + serializedNode.getVarType, + serializedNode.environmentVariables, + serializedNode.conversationVariables, + serializedNode.ragVariables, ) return node @@ -152,11 +203,15 @@ export class HITLInputNode extends DecoratorNode { version: 1, variableName: this.getVariableName(), nodeId: this.getNodeId(), - nodeTitle: this.getNodeTitle(), formInputs: this.getFormInputs(), onFormInputsChange: this.getOnFormInputsChange(), onFormInputItemRename: this.getOnFormInputItemRename(), onFormInputItemRemove: this.getOnFormInputItemRemove(), + workflowNodesMap: this.getWorkflowNodesMap(), + getVarType: this.getGetVarType(), + environmentVariables: this.getEnvironmentVariables(), + conversationVariables: this.getConversationVariables(), + ragVariables: this.getRagVariables(), } } @@ -168,20 +223,28 @@ export class HITLInputNode extends DecoratorNode { export function $createHITLInputNode( variableName: string, nodeId: string, - nodeTitle: string, formInputs: FormInputItem[], onFormInputsChange: (inputs: FormInputItem[]) => void, onFormInputItemRename: (payload: FormInputItem, oldName: string) => void, onFormInputItemRemove: (varName: string) => void, + workflowNodesMap: WorkflowNodesMap, + getVarType?: GetVarType, + environmentVariables?: Var[], + conversationVariables?: Var[], + ragVariables?: Var[], ): HITLInputNode { return new HITLInputNode( variableName, nodeId, - nodeTitle, formInputs, onFormInputsChange, onFormInputItemRename, onFormInputItemRemove, + workflowNodesMap, + getVarType, + environmentVariables, + conversationVariables, + ragVariables, ) } diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/variable-block.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/variable-block.tsx new file mode 100644 index 0000000000..c41dfdc477 --- /dev/null +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/variable-block.tsx @@ -0,0 +1,145 @@ +import { + memo, + useEffect, + useMemo, + useState, +} from 'react' +import { useTranslation } from 'react-i18next' +import { + COMMAND_PRIORITY_EDITOR, +} from 'lexical' +import { mergeRegister } from '@lexical/utils' +import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' +import type { WorkflowNodesMap } from '../workflow-variable-block/node' +import { + isConversationVar, + isENV, + isGlobalVar, + isRagVariableVar, + isSystemVar, +} from '@/app/components/workflow/nodes/_base/components/variable/utils' +import Tooltip from '@/app/components/base/tooltip' +import { isExceptionVariable } from '@/app/components/workflow/utils' +import VarFullPathPanel from '@/app/components/workflow/nodes/_base/components/variable/var-full-path-panel' +import { Type } from '@/app/components/workflow/nodes/llm/types' +import type { ValueSelector, Var } from '@/app/components/workflow/types' +import { + VariableLabelInEditor, +} from '@/app/components/workflow/nodes/_base/components/variable/variable-label' +import { UPDATE_WORKFLOW_NODES_MAP } from '../workflow-variable-block' +import { HITLInputNode } from './node' + +type HITLInputVariableBlockComponentProps = { + variables: string[] + workflowNodesMap: WorkflowNodesMap + environmentVariables?: Var[] + conversationVariables?: Var[] + ragVariables?: Var[] + getVarType?: (payload: { + nodeId: string, + valueSelector: ValueSelector, + }) => Type +} + +const HITLInputVariableBlockComponent = ({ + variables, + workflowNodesMap = {}, + getVarType, + environmentVariables, + conversationVariables, + ragVariables, +}: HITLInputVariableBlockComponentProps) => { + const { t } = useTranslation() + const [editor] = useLexicalComposerContext() + const variablesLength = variables.length + const isRagVar = isRagVariableVar(variables) + const isShowAPart = variablesLength > 2 && !isRagVar + const varName = ( + () => { + const isSystem = isSystemVar(variables) + const varName = variables[variablesLength - 1] + return `${isSystem ? 'sys.' : ''}${varName}` + } + )() + const [localWorkflowNodesMap, setLocalWorkflowNodesMap] = useState(workflowNodesMap) + const node = localWorkflowNodesMap![variables[isRagVar ? 1 : 0]] + + const isException = isExceptionVariable(varName, node?.type) + const variableValid = useMemo(() => { + let variableValid = true + const isEnv = isENV(variables) + const isChatVar = isConversationVar(variables) + const isGlobal = isGlobalVar(variables) + if (isGlobal) + return true + + if (isEnv) { + if (environmentVariables) + variableValid = environmentVariables.some(v => v.variable === `${variables?.[0] ?? ''}.${variables?.[1] ?? ''}`) + } + else if (isChatVar) { + if (conversationVariables) + variableValid = conversationVariables.some(v => v.variable === `${variables?.[0] ?? ''}.${variables?.[1] ?? ''}`) + } + else if (isRagVar) { + if (ragVariables) + variableValid = ragVariables.some(v => v.variable === `${variables?.[0] ?? ''}.${variables?.[1] ?? ''}.${variables?.[2] ?? ''}`) + } + else { + variableValid = !!node + } + return variableValid + }, [variables, node, environmentVariables, conversationVariables, isRagVar, ragVariables]) + + useEffect(() => { + if (!editor.hasNodes([HITLInputNode])) + throw new Error('HITLInputNodePlugin: HITLInputNode not registered on editor') + + return mergeRegister( + editor.registerCommand( + UPDATE_WORKFLOW_NODES_MAP, + (workflowNodesMap: WorkflowNodesMap) => { + setLocalWorkflowNodesMap(workflowNodesMap) + + return true + }, + COMMAND_PRIORITY_EDITOR, + ), + ) + }, [editor]) + + const Item = ( + + ) + + if (!node) + return Item + + return ( + } + disabled={!isShowAPart} + > +
{Item}
+
+ ) +} + +export default memo(HITLInputVariableBlockComponent) diff --git a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.tsx b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.tsx index 62b9cccb3f..c70cbd6ffd 100644 --- a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.tsx +++ b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.tsx @@ -40,7 +40,7 @@ const WorkflowVariableBlockReplacementBlock = ({ const nodePathString = textNode.getTextContent().slice(3, -3) return $applyNodeReplacement($createWorkflowVariableBlockNode(nodePathString.split('.'), workflowNodesMap, getVarType, variables?.find(o => o.nodeId === 'env')?.vars || [], variables?.find(o => o.nodeId === 'conversation')?.vars || [], ragVariables)) - }, [onInsert, workflowNodesMap, getVarType, variables]) + }, [onInsert, workflowNodesMap, getVarType, variables, ragVariables]) const getMatch = useCallback((text: string) => { const matchArr = REGEX.exec(text) diff --git a/web/app/components/base/prompt-editor/types.ts b/web/app/components/base/prompt-editor/types.ts index bd7ca3dd34..93ca29b83c 100644 --- a/web/app/components/base/prompt-editor/types.ts +++ b/web/app/components/base/prompt-editor/types.ts @@ -84,11 +84,15 @@ export type WorkflowVariableBlockType = { export type HITLInputBlockType = { show?: boolean nodeId: string - nodeTitle: string formInputs?: FormInputItem[] + variables?: NodeOutPutVar[] + workflowNodesMap?: Record> + getVarType?: GetVarType onFormInputsChange?: (inputs: FormInputItem[]) => void onFormInputItemRemove: (varName: string) => void onFormInputItemRename: (payload: FormInputItem, oldName: string) => void + onInsert?: () => void + onDelete?: () => void } export type MenuTextMatch = { diff --git a/web/app/components/workflow/nodes/human-input/components/form-content.tsx b/web/app/components/workflow/nodes/human-input/components/form-content.tsx index f51e33f610..5471a220b8 100644 --- a/web/app/components/workflow/nodes/human-input/components/form-content.tsx +++ b/web/app/components/workflow/nodes/human-input/components/form-content.tsx @@ -14,9 +14,8 @@ import { isMac } from '../../../utils' import { useBoolean } from 'ahooks' import { cn } from '@/utils/classnames' -type Props = { +type FormContentProps = { nodeId: string - nodeTitle: string value: string onChange: (value: string) => void formInputs: FormInputItem[] @@ -35,9 +34,8 @@ const CtrlKey: FC = () => { return {isMac() ? '⌘' : 'Ctrl'} } -const FormContent: FC = ({ +const FormContent: FC = ({ nodeId, - nodeTitle, value, onChange, formInputs, @@ -67,7 +65,6 @@ const FormContent: FC = ({ onInsert(INSERT_HITL_INPUT_BLOCK_COMMAND, { variableName: payload.output_variable_name, nodeId, - nodeTitle, formInputs: newFormInputs, onFormInputsChange, onFormInputItemRename, @@ -91,6 +88,23 @@ const FormContent: FC = ({ setFalse: setBlur, }] = useBoolean(false) + const workflowNodesMap = availableNodes.reduce((acc: any, node) => { + acc[node.id] = { + title: node.data.title, + type: node.data.type, + width: node.width, + height: node.height, + position: node.position, + } + if (node.data.type === BlockEnum.Start) { + acc.sys = { + title: t('workflow.blocks.start'), + type: BlockEnum.Start, + } + } + return acc + }, {}) + return (
= ({ show: true, formInputs, nodeId, - nodeTitle, onFormInputsChange, onFormInputItemRename, onFormInputItemRemove, + variables: availableVars || [], + workflowNodesMap, + getVarType, }} workflowVariableBlock={{ show: true, variables: availableVars || [], getVarType: getVarType as any, - workflowNodesMap: availableNodes.reduce((acc: any, node) => { - acc[node.id] = { - title: node.data.title, - type: node.data.type, - width: node.width, - height: node.height, - position: node.position, - } - if (node.data.type === BlockEnum.Start) { - acc.sys = { - title: t('workflow.blocks.start'), - type: BlockEnum.Start, - } - } - return acc - }, {}), + workflowNodesMap, }} editable shortcutPopups={[{ diff --git a/web/app/components/workflow/nodes/human-input/panel.tsx b/web/app/components/workflow/nodes/human-input/panel.tsx index e9ecf85bca..4a4cbf48ce 100644 --- a/web/app/components/workflow/nodes/human-input/panel.tsx +++ b/web/app/components/workflow/nodes/human-input/panel.tsx @@ -115,7 +115,6 @@ const Panel: FC> = ({ nodeId={id} value={inputs.form_content} onChange={handleFormContentChange} - nodeTitle={inputs.title} formInputs={inputs.inputs} onFormInputsChange={handleFormInputsChange} onFormInputItemRename={handleFormInputItemRename}