From 777cca1a099f9e1525367c6cdeb7aede40886067 Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 15 Mar 2024 20:50:55 +0800 Subject: [PATCH] feat: question classify init --- .../components/workflow/nodes/code/panel.tsx | 2 + .../workflow/nodes/code/use-config.ts | 7 ++ .../if-else/components/condition-item.tsx | 9 ++- .../if-else/components/condition-list.tsx | 5 ++ .../workflow/nodes/if-else/panel.tsx | 2 + .../workflow/nodes/if-else/use-config.ts | 13 +++- .../nodes/knowledge-retrieval/use-config.ts | 19 +++--- .../nodes/question-classifier/panel.tsx | 19 +----- .../nodes/question-classifier/use-config.ts | 64 +++++++++++++++++-- .../nodes/template-transform/panel.tsx | 2 + .../nodes/template-transform/use-config.ts | 11 +++- 11 files changed, 115 insertions(+), 38 deletions(-) diff --git a/web/app/components/workflow/nodes/code/panel.tsx b/web/app/components/workflow/nodes/code/panel.tsx index f03d41bfea..131257035b 100644 --- a/web/app/components/workflow/nodes/code/panel.tsx +++ b/web/app/components/workflow/nodes/code/panel.tsx @@ -41,6 +41,7 @@ const Panel: FC> = ({ handleCodeLanguageChange, handleVarsChange, handleAddOutputVariable, + filterVar, // single run isShowSingleRun, hideSingleRun, @@ -67,6 +68,7 @@ const Panel: FC> = ({ nodeId={id} list={inputs.variables} onChange={handleVarListChange} + filterVar={filterVar} /> diff --git a/web/app/components/workflow/nodes/code/use-config.ts b/web/app/components/workflow/nodes/code/use-config.ts index 1df9e5381f..7f6768a398 100644 --- a/web/app/components/workflow/nodes/code/use-config.ts +++ b/web/app/components/workflow/nodes/code/use-config.ts @@ -2,6 +2,8 @@ import { useCallback } from 'react' import produce from 'immer' import useVarList from '../_base/hooks/use-var-list' import useOutputVarList from '../_base/hooks/use-output-var-list' +import { VarType } from '../../types' +import type { Var } from '../../types' import type { CodeLanguage, CodeNodeType } 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' @@ -32,6 +34,10 @@ const useConfig = (id: string, payload: CodeNodeType) => { setInputs, }) + const filterVar = useCallback((varPayload: Var) => { + return [VarType.string, VarType.number, VarType.object, VarType.array, VarType.arrayNumber, VarType.arrayString, VarType.arrayObject].includes(varPayload.type) + }, []) + // single run const { isShowSingleRun, @@ -72,6 +78,7 @@ const useConfig = (id: string, payload: CodeNodeType) => { handleCodeChange, handleCodeLanguageChange, handleVarsChange, + filterVar, handleAddOutputVariable, // single run isShowSingleRun, diff --git a/web/app/components/workflow/nodes/if-else/components/condition-item.tsx b/web/app/components/workflow/nodes/if-else/components/condition-item.tsx index 2ee7f08cd6..9102bb3e68 100644 --- a/web/app/components/workflow/nodes/if-else/components/condition-item.tsx +++ b/web/app/components/workflow/nodes/if-else/components/condition-item.tsx @@ -7,7 +7,7 @@ import VarReferencePicker from '../../_base/components/variable/var-reference-pi import { isComparisonOperatorNeedTranslate } from '../utils' import type { Condition } from '@/app/components/workflow/nodes/if-else/types' import { ComparisonOperator, LogicalOperator } from '@/app/components/workflow/nodes/if-else/types' -import type { ValueSelector } from '@/app/components/workflow/types' +import type { ValueSelector, Var } from '@/app/components/workflow/types' import { Trash03 } from '@/app/components/base/icons/src/vender/line/general' import { RefreshCw05 } from '@/app/components/base/icons/src/vender/line/arrows' import Selector from '@/app/components/workflow/nodes/_base/components/selector' @@ -73,6 +73,7 @@ type ItemProps = { isShowLogicalOperator?: boolean logicalOperator: LogicalOperator onLogicalOperatorToggle: () => void + filterVar: (varPayload: Var) => boolean } const Item: FC = ({ @@ -85,14 +86,15 @@ const Item: FC = ({ isShowLogicalOperator, logicalOperator, onLogicalOperatorToggle, + filterVar, }) => { const { t } = useTranslation() const isValueReadOnly = [ComparisonOperator.empty, ComparisonOperator.notEmpty, ComparisonOperator.isNull, ComparisonOperator.isNotNull].includes(payload.comparison_operator) - const handleVarReferenceChange = useCallback((value: ValueSelector) => { + const handleVarReferenceChange = useCallback((value: ValueSelector | string) => { onChange({ ...payload, - variable_selector: value, + variable_selector: value as ValueSelector, }) // TODO: handle value type change will effect the comparisonOperators }, [onChange, payload]) @@ -140,6 +142,7 @@ const Item: FC = ({ className='grow' value={payload.variable_selector} onChange={handleVarReferenceChange} + filterVar={filterVar} /> void logicalOperator: LogicalOperator onLogicalOperatorToggle: () => void + filterVar: (varPayload: Var) => boolean } const ConditionList: FC = ({ @@ -24,6 +26,7 @@ const ConditionList: FC = ({ onChange, logicalOperator, onLogicalOperatorToggle, + filterVar, }) => { const handleItemChange = useCallback((index: number) => { return (newItem: Condition) => { @@ -59,6 +62,7 @@ const ConditionList: FC = ({ onRemove={handleItemRemove(0)} logicalOperator={logicalOperator} onLogicalOperatorToggle={onLogicalOperatorToggle} + filterVar={filterVar} /> { list.length > 1 && ( @@ -74,6 +78,7 @@ const ConditionList: FC = ({ isShowLogicalOperator logicalOperator={logicalOperator} onLogicalOperatorToggle={onLogicalOperatorToggle} + filterVar={filterVar} /> ))) } diff --git a/web/app/components/workflow/nodes/if-else/panel.tsx b/web/app/components/workflow/nodes/if-else/panel.tsx index 5cbe28be7b..d3dd3be053 100644 --- a/web/app/components/workflow/nodes/if-else/panel.tsx +++ b/web/app/components/workflow/nodes/if-else/panel.tsx @@ -22,6 +22,7 @@ const Panel: FC> = ({ handleConditionsChange, handleAddCondition, handleLogicalOperatorToggle, + filterVar, } = useConfig(id, data) return (
@@ -38,6 +39,7 @@ const Panel: FC> = ({ onChange={handleConditionsChange} logicalOperator={inputs.logical_operator} onLogicalOperatorToggle={handleLogicalOperatorToggle} + filterVar={filterVar} /> { draft.conditions = newConditions }) setInputs(newInputs) - }, []) + }, [inputs, setInputs]) const handleAddCondition = useCallback(() => { const newInputs = produce(inputs, (draft) => { @@ -24,20 +26,25 @@ const useConfig = (id: string, payload: IfElseNodeType) => { }) }) setInputs(newInputs) - }, [inputs]) + }, [inputs, setInputs]) const handleLogicalOperatorToggle = useCallback(() => { const newInputs = produce(inputs, (draft) => { draft.logical_operator = draft.logical_operator === LogicalOperator.and ? LogicalOperator.or : LogicalOperator.and }) setInputs(newInputs) - }, [inputs]) + }, [inputs, setInputs]) + + const filterVar = useCallback((varPayload: Var) => { + return varPayload.type !== VarType.arrayFile + }, []) return { inputs, handleConditionsChange, handleAddCondition, handleLogicalOperatorToggle, + filterVar, } } diff --git a/web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts b/web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts index e37e1ce9ca..81d4731239 100644 --- a/web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts +++ b/web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts @@ -12,6 +12,7 @@ import useOneStepRun from '@/app/components/workflow/nodes/_base/hooks/use-one-s const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => { const isChatMode = useIsChatMode() + console.log() const { getBeforeNodesInSameBranch } = useWorkflow() const startNode = getBeforeNodesInSameBranch(id).find(node => node.data.type === BlockEnum.Start) const startNodeId = startNode?.id @@ -55,14 +56,16 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => { }, []) useEffect(() => { - if (inputs._isReady) { - if (isChatMode && inputs.query_variable_selector.length === 0 && startNodeId) { - handleQueryVarChange( - [startNodeId, 'sys.query'], - ) - } - } - }, [inputs._isReady]) + let query_variable_selector: ValueSelector = [] + if (isChatMode && inputs.query_variable_selector.length === 0 && startNodeId) + query_variable_selector = [startNodeId, 'sys.query'] + + setInputs({ + ...inputs, + query_variable_selector, + }) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) const handleOnDatasetsChange = useCallback((newDatasets: DataSet[]) => { const newInputs = produce(inputs, (draft) => { diff --git a/web/app/components/workflow/nodes/question-classifier/panel.tsx b/web/app/components/workflow/nodes/question-classifier/panel.tsx index e094275ada..52919ad885 100644 --- a/web/app/components/workflow/nodes/question-classifier/panel.tsx +++ b/web/app/components/workflow/nodes/question-classifier/panel.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react' -import React, { useEffect } from 'react' +import React from 'react' import { useTranslation } from 'react-i18next' import VarReferencePicker from '../_base/components/variable/var-reference-picker' import useConfig from './use-config' @@ -11,7 +11,6 @@ import ModelParameterModal from '@/app/components/header/account-setting/model-p 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 { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks' const i18nPrefix = 'workflow.nodes.questionClassifiers' @@ -21,10 +20,6 @@ const Panel: FC> = ({ }) => { const { t } = useTranslation() const readOnly = false - const { - currentProvider, - currentModel, - } = useModelListAndDefaultModelAndCurrentProviderAndModel(1) const { inputs, @@ -42,20 +37,11 @@ const Panel: FC> = ({ query, setQuery, runResult, + filterVar, } = useConfig(id, data) const model = inputs.model - useEffect(() => { - if (currentProvider?.provider && currentModel?.model && !model.provider) { - handleModelChanged({ - provider: currentProvider?.provider, - modelId: currentModel?.model, - mode: currentModel?.model_properties?.mode as string, - }) - } - }, [model.provider, currentProvider, currentModel, handleModelChanged]) - return (
@@ -68,6 +54,7 @@ const Panel: FC> = ({ nodeId={id} value={inputs.query_variable_selector} onChange={handleQueryVarChange} + filterVar={filterVar} /> { + const isChatMode = useIsChatMode() + const defaultConfig = useStore(s => s.nodesDefaultConfigs)[payload.type] + const { getBeforeNodesInSameBranch } = useWorkflow() + const startNode = getBeforeNodesInSameBranch(id).find(node => node.data.type === BlockEnum.Start) + const startNodeId = startNode?.id const { inputs, setInputs } = useNodeCrud(id, payload) + const inputRef = useRef(inputs) + useEffect(() => { + inputRef.current = inputs + }, [inputs]) // model + const { + currentProvider, + currentModel, + } = useModelListAndDefaultModelAndCurrentProviderAndModel(1) + + const model = inputs.model + const handleModelChanged = useCallback((model: { provider: string; modelId: string; mode?: string }) => { - const newInputs = produce(inputs, (draft) => { + const newInputs = produce(inputRef.current, (draft) => { draft.model.provider = model.provider draft.model.name = model.modelId draft.model.mode = model.mode! }) setInputs(newInputs) - }, [inputs, setInputs]) + }, [setInputs]) + + useEffect(() => { + if (currentProvider?.provider && currentModel?.model && !model.provider) { + handleModelChanged({ + provider: currentProvider?.provider, + modelId: currentModel?.model, + mode: currentModel?.model_properties?.mode as string, + }) + } + }, [model.provider, currentProvider, currentModel, handleModelChanged]) const handleCompletionParamsChange = useCallback((newParams: Record) => { const newInputs = produce(inputs, (draft) => { @@ -25,13 +55,30 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => { setInputs(newInputs) }, [inputs, setInputs]) - const handleQueryVarChange = useCallback((newVar: ValueSelector) => { + const handleQueryVarChange = useCallback((newVar: ValueSelector | string) => { const newInputs = produce(inputs, (draft) => { - draft.query_variable_selector = newVar + draft.query_variable_selector = newVar as ValueSelector }) setInputs(newInputs) + // console.log(newInputs.query_variable_selector) }, [inputs, setInputs]) + useEffect(() => { + const isReady = defaultConfig && Object.keys(defaultConfig).length > 0 + if (isReady) { + let query_variable_selector: ValueSelector = [] + if (isChatMode && inputs.query_variable_selector.length === 0 && startNodeId) + query_variable_selector = [startNodeId, 'sys.query'] + setInputs({ + ...inputs, + ...defaultConfig, + query_variable_selector: inputs.query_variable_selector.length > 0 ? inputs.query_variable_selector : query_variable_selector, + }) + console.log(query_variable_selector) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [defaultConfig]) + const handleClassesChange = useCallback((newClasses: any) => { const newInputs = produce(inputs, (draft) => { draft.classes = newClasses @@ -80,11 +127,16 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => { }) }, [runInputData, setRunInputData]) + const filterVar = useCallback((varPayload: Var) => { + return varPayload.type === VarType.string + }, []) + return { inputs, handleModelChanged, handleCompletionParamsChange, handleQueryVarChange, + filterVar, handleTopicsChange: handleClassesChange, handleInstructionChange, handleMemoryChange, diff --git a/web/app/components/workflow/nodes/template-transform/panel.tsx b/web/app/components/workflow/nodes/template-transform/panel.tsx index 725e4f67b2..b3f336ef3d 100644 --- a/web/app/components/workflow/nodes/template-transform/panel.tsx +++ b/web/app/components/workflow/nodes/template-transform/panel.tsx @@ -29,6 +29,7 @@ const Panel: FC> = ({ handleVarListChange, handleAddVariable, handleCodeChange, + filterVar, // single run isShowSingleRun, hideSingleRun, @@ -56,6 +57,7 @@ const Panel: FC> = ({ readonly={readOnly} list={inputs.variables} onChange={handleVarListChange} + filterVar={filterVar} /> diff --git a/web/app/components/workflow/nodes/template-transform/use-config.ts b/web/app/components/workflow/nodes/template-transform/use-config.ts index 534bec9ea4..c5235fde1d 100644 --- a/web/app/components/workflow/nodes/template-transform/use-config.ts +++ b/web/app/components/workflow/nodes/template-transform/use-config.ts @@ -1,6 +1,8 @@ import { useCallback } from 'react' import produce from 'immer' import useVarList from '../_base/hooks/use-var-list' +import type { Var } from '../../types' +import { VarType } from '../../types' import type { TemplateTransformNodeType } 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' @@ -17,7 +19,7 @@ const useConfig = (id: string, payload: TemplateTransformNodeType) => { draft.template = template }) setInputs(newInputs) - }, [setInputs]) + }, [inputs, setInputs]) // single run const { @@ -48,13 +50,18 @@ const useConfig = (id: string, payload: TemplateTransformNodeType) => { const setInputVarValues = useCallback((newPayload: Record) => { setRunInputData(newPayload) - }, [runInputData, setRunInputData]) + }, [setRunInputData]) + + const filterVar = useCallback((varPayload: Var) => { + return [VarType.string, VarType.number, VarType.object, VarType.array, VarType.arrayNumber, VarType.arrayString, VarType.arrayObject].includes(varPayload.type) + }, []) return { inputs, handleVarListChange, handleAddVariable, handleCodeChange, + filterVar, // single run isShowSingleRun, hideSingleRun,