diff --git a/web/app/components/workflow/nodes/_base/components/workflow-panel/last-run/use-last-run.ts b/web/app/components/workflow/nodes/_base/components/workflow-panel/last-run/use-last-run.ts index 485bf58435..379e8ef79c 100644 --- a/web/app/components/workflow/nodes/_base/components/workflow-panel/last-run/use-last-run.ts +++ b/web/app/components/workflow/nodes/_base/components/workflow-panel/last-run/use-last-run.ts @@ -8,6 +8,7 @@ import useLLMSingleRunFormParams from '@/app/components/workflow/nodes/llm/use-s import useKnowledgeRetrievalSingleRunFormParams from '../../../../knowledge-retrieval/use-single-run-form-params' import useCodeSingleRunFormParams from '../../../../code/use-single-run-form-params' import useTemplateTransformSingleRunFormParams from '../../../../template-transform/use-single-run-form-params' +import useQuestionClassifierSingleRunFormParams from '../../../../question-classifier/use-single-run-form-params' import { BlockEnum } from '@/app/components/workflow/types' import { useNodesSyncDraft, @@ -18,10 +19,10 @@ const singleRunFormParamsHooks: Record = { [BlockEnum.KnowledgeRetrieval]: useKnowledgeRetrievalSingleRunFormParams, [BlockEnum.Code]: useCodeSingleRunFormParams, [BlockEnum.TemplateTransform]: useTemplateTransformSingleRunFormParams, + [BlockEnum.QuestionClassifier]: useQuestionClassifierSingleRunFormParams, [BlockEnum.Start]: undefined, [BlockEnum.End]: undefined, [BlockEnum.Answer]: undefined, - [BlockEnum.QuestionClassifier]: undefined, [BlockEnum.IfElse]: undefined, [BlockEnum.HttpRequest]: undefined, [BlockEnum.VariableAssigner]: undefined, diff --git a/web/app/components/workflow/nodes/question-classifier/panel.tsx b/web/app/components/workflow/nodes/question-classifier/panel.tsx index 96e8fabd47..6e31e56fb2 100644 --- a/web/app/components/workflow/nodes/question-classifier/panel.tsx +++ b/web/app/components/workflow/nodes/question-classifier/panel.tsx @@ -3,20 +3,16 @@ import React from 'react' import { useTranslation } from 'react-i18next' import VarReferencePicker from '../_base/components/variable/var-reference-picker' import ConfigVision from '../_base/components/config-vision' -import { findVariableWhenOnLLMVision } from '../utils' import useConfig from './use-config' import ClassList from './components/class-list' import AdvancedSetting from './components/advanced-setting' import type { QuestionClassifierNodeType } from './types' import Field from '@/app/components/workflow/nodes/_base/components/field' import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal' -import { InputVarType, type NodePanelProps } from '@/app/components/workflow/types' -import BeforeRunForm from '@/app/components/workflow/nodes/_base/components/before-run-form' -import ResultPanel from '@/app/components/workflow/run/result-panel' +import type { NodePanelProps } from '@/app/components/workflow/types' import Split from '@/app/components/workflow/nodes/_base/components/split' import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars' import { FieldCollapse } from '@/app/components/workflow/nodes/_base/components/collapse' -import type { Props as FormProps } from '@/app/components/workflow/nodes/_base/components/before-run-form/form' const i18nPrefix = 'workflow.nodes.questionClassifiers' @@ -38,66 +34,16 @@ const Panel: FC> = ({ hasSetBlockStatus, availableVars, availableNodesWithParent, - availableVisionVars, handleInstructionChange, - inputVarValues, - varInputs, - setInputVarValues, handleMemoryChange, isVisionModel, handleVisionResolutionChange, handleVisionResolutionEnabledChange, - isShowSingleRun, - hideSingleRun, - runningStatus, - handleRun, - handleStop, - runResult, filterVar, - visionFiles, - setVisionFiles, } = useConfig(id, data) const model = inputs.model - const singleRunForms = (() => { - const forms: FormProps[] = [] - - forms.push( - { - label: t('workflow.nodes.llm.singleRun.variable')!, - inputs: [{ - label: t(`${i18nPrefix}.inputVars`)!, - variable: 'query', - type: InputVarType.paragraph, - required: true, - }, ...varInputs], - values: inputVarValues, - onChange: setInputVarValues, - }, - ) - - if (isVisionModel && data.vision?.enabled && data.vision?.configs?.variable_selector) { - const currentVariable = findVariableWhenOnLLMVision(data.vision.configs.variable_selector, availableVisionVars) - - forms.push( - { - label: t('workflow.nodes.llm.vision')!, - inputs: [{ - label: currentVariable?.variable as any, - variable: '#files#', - type: currentVariable?.formType as any, - required: false, - }], - values: { '#files#': visionFiles }, - onChange: keyValue => setVisionFiles(keyValue['#files#']), - }, - ) - } - - return forms - })() - return (
@@ -183,17 +129,6 @@ const Panel: FC> = ({
- {isShowSingleRun && ( - } - /> - )}
) } diff --git a/web/app/components/workflow/nodes/question-classifier/use-config.ts b/web/app/components/workflow/nodes/question-classifier/use-config.ts index 7df8293b40..8eacf5b43f 100644 --- a/web/app/components/workflow/nodes/question-classifier/use-config.ts +++ b/web/app/components/workflow/nodes/question-classifier/use-config.ts @@ -11,7 +11,6 @@ import useAvailableVarList from '../_base/hooks/use-available-var-list' import useConfigVision from '../../hooks/use-config-vision' import type { QuestionClassifierNodeType } from './types' import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud' -import useOneStepRun from '@/app/components/workflow/nodes/_base/hooks/use-one-step-run' import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks' import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import { checkHasQueryBlock } from '@/app/components/base/prompt-editor/constants' @@ -87,7 +86,7 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => { return setModelChanged(false) handleVisionConfigAfterModelChanged() - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isVisionModel, modelChanged]) const handleQueryVarChange = useCallback((newVar: ValueSelector | string) => { @@ -109,7 +108,7 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => { query_variable_selector: inputs.query_variable_selector.length > 0 ? inputs.query_variable_selector : query_variable_selector, }) } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [defaultConfig]) const handleClassesChange = useCallback((newClasses: any) => { @@ -163,59 +162,6 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => { setInputs(newInputs) }, [inputs, setInputs]) - // single run - const { - isShowSingleRun, - hideSingleRun, - getInputVars, - runningStatus, - handleRun, - handleStop, - runInputData, - runInputDataRef, - setRunInputData, - runResult, - } = useOneStepRun({ - id, - data: inputs, - defaultRunInputData: { - 'query': '', - '#files#': [], - }, - }) - - const query = runInputData.query - const setQuery = useCallback((newQuery: string) => { - setRunInputData({ - ...runInputData, - query: newQuery, - }) - }, [runInputData, setRunInputData]) - - const varInputs = getInputVars([inputs.instruction]) - const inputVarValues = (() => { - const vars: Record = { - query, - } - Object.keys(runInputData) - .forEach((key) => { - vars[key] = runInputData[key] - }) - return vars - })() - - const setInputVarValues = useCallback((newPayload: Record) => { - setRunInputData(newPayload) - }, [setRunInputData]) - - const visionFiles = runInputData['#files#'] - const setVisionFiles = useCallback((newFiles: any[]) => { - setRunInputData({ - ...runInputDataRef.current, - '#files#': newFiles, - }) - }, [runInputDataRef, setRunInputData]) - const filterVar = useCallback((varPayload: Var) => { return varPayload.type === VarType.string }, []) @@ -235,23 +181,10 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => { availableNodesWithParent, availableVisionVars, handleInstructionChange, - varInputs, - inputVarValues, - setInputVarValues, handleMemoryChange, isVisionModel, handleVisionResolutionEnabledChange, handleVisionResolutionChange, - isShowSingleRun, - hideSingleRun, - runningStatus, - handleRun, - handleStop, - query, - setQuery, - runResult, - visionFiles, - setVisionFiles, } } diff --git a/web/app/components/workflow/nodes/question-classifier/use-single-run-form-params.ts b/web/app/components/workflow/nodes/question-classifier/use-single-run-form-params.ts new file mode 100644 index 0000000000..a3a7c20cfa --- /dev/null +++ b/web/app/components/workflow/nodes/question-classifier/use-single-run-form-params.ts @@ -0,0 +1,126 @@ +import type { MutableRefObject } from 'react' +import { useTranslation } from 'react-i18next' +import type { Props as FormProps } from '@/app/components/workflow/nodes/_base/components/before-run-form/form' +import type { InputVar, Var, Variable } from '@/app/components/workflow/types' +import { InputVarType, VarType } from '@/app/components/workflow/types' +import type { QuestionClassifierNodeType } from './types' +import useNodeCrud from '../_base/hooks/use-node-crud' +import { useCallback } from 'react' +import useConfigVision from '../../hooks/use-config-vision' +import { noop } from 'lodash-es' +import { findVariableWhenOnLLMVision } from '../utils' +import useAvailableVarList from '../_base/hooks/use-available-var-list' + +const i18nPrefix = 'workflow.nodes.questionClassifiers' + +type Params = { + id: string, + payload: QuestionClassifierNodeType, + runInputData: Record + runInputDataRef: MutableRefObject> + getInputVars: (textList: string[]) => InputVar[] + setRunInputData: (data: Record) => void + toVarInputs: (variables: Variable[]) => InputVar[] +} +const useSingleRunFormParams = ({ + id, + payload, + runInputData, + runInputDataRef, + getInputVars, + setRunInputData, +}: Params) => { + const { t } = useTranslation() + const { inputs } = useNodeCrud(id, payload) + + const model = inputs.model + + const { + isVisionModel, + } = useConfigVision(model, { + payload: inputs.vision, + onChange: noop, + }) + + const visionFiles = runInputData['#files#'] + const setVisionFiles = useCallback((newFiles: any[]) => { + setRunInputData?.({ + ...runInputDataRef.current, + '#files#': newFiles, + }) + }, [runInputDataRef, setRunInputData]) + + const varInputs = getInputVars([inputs.instruction]) + + const inputVarValues = (() => { + const vars: Record = {} + Object.keys(runInputData) + .filter(key => !['#context#', '#files#'].includes(key)) + .forEach((key) => { + vars[key] = runInputData[key] + }) + return vars + })() + + const setInputVarValues = useCallback((newPayload: Record) => { + const newVars = { + ...newPayload, + '#context#': runInputDataRef.current['#context#'], + '#files#': runInputDataRef.current['#files#'], + } + setRunInputData?.(newVars) + }, [runInputDataRef, setRunInputData]) + + const filterVisionInputVar = useCallback((varPayload: Var) => { + return [VarType.file, VarType.arrayFile].includes(varPayload.type) + }, []) + const { + availableVars: availableVisionVars, + } = useAvailableVarList(id, { + onlyLeafNodeVar: false, + filterVar: filterVisionInputVar, + }) + + const forms = (() => { + const forms: FormProps[] = [] + + forms.push( + { + label: t('workflow.nodes.llm.singleRun.variable')!, + inputs: [{ + label: t(`${i18nPrefix}.inputVars`)!, + variable: 'query', + type: InputVarType.paragraph, + required: true, + }, ...varInputs], + values: inputVarValues, + onChange: setInputVarValues, + }, + ) + + if (isVisionModel && payload.vision?.enabled && payload.vision?.configs?.variable_selector) { + const currentVariable = findVariableWhenOnLLMVision(payload.vision.configs.variable_selector, availableVisionVars) + + forms.push( + { + label: t('workflow.nodes.llm.vision')!, + inputs: [{ + label: currentVariable?.variable as any, + variable: '#files#', + type: currentVariable?.formType as any, + required: false, + }], + values: { '#files#': visionFiles }, + onChange: keyValue => setVisionFiles(keyValue['#files#']), + }, + ) + } + return forms + })() + + return { + forms, + } +} + +export default useSingleRunFormParams