mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-05-13 04:58:15 +08:00

Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Patryk Garstecki <patryk20120@yahoo.pl> Co-authored-by: Sebastian.W <thiner@gmail.com> Co-authored-by: 呆萌闷油瓶 <253605712@qq.com> Co-authored-by: takatost <takatost@users.noreply.github.com> Co-authored-by: rechardwang <wh_goodjob@163.com> Co-authored-by: Nite Knite <nkCoding@gmail.com> Co-authored-by: Chenhe Gu <guchenhe@gmail.com> Co-authored-by: Joshua <138381132+joshua20231026@users.noreply.github.com> Co-authored-by: Weaxs <459312872@qq.com> Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com> Co-authored-by: leejoo0 <81673835+leejoo0@users.noreply.github.com> Co-authored-by: JzoNg <jzongcode@gmail.com> Co-authored-by: sino <sino2322@gmail.com> Co-authored-by: Vikey Chen <vikeytk@gmail.com> Co-authored-by: wanghl <Wang-HL@users.noreply.github.com> Co-authored-by: Haolin Wang-汪皓临 <haolin.wang@atlaslovestravel.com> Co-authored-by: Zixuan Cheng <61724187+Theysua@users.noreply.github.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: Bowen Liang <bowenliang@apache.org> Co-authored-by: Bowen Liang <liangbowen@gf.com.cn> Co-authored-by: fanghongtai <42790567+fanghongtai@users.noreply.github.com> Co-authored-by: wxfanghongtai <wxfanghongtai@gf.com.cn> Co-authored-by: Matri <qjp@bithuman.io> Co-authored-by: Benjamin <benjaminx@gmail.com>
259 lines
8.2 KiB
TypeScript
259 lines
8.2 KiB
TypeScript
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
import produce from 'immer'
|
|
import type { Memory, MoreInfo, ValueSelector, Var } from '../../types'
|
|
import { ChangeType, VarType } from '../../types'
|
|
import { useStore } from '../../store'
|
|
import {
|
|
useIsChatMode,
|
|
useNodesReadOnly,
|
|
useWorkflow,
|
|
} from '../../hooks'
|
|
import useOneStepRun from '../_base/hooks/use-one-step-run'
|
|
import type { Param, ParameterExtractorNodeType, ReasoningModeType } from './types'
|
|
import { useModelListAndDefaultModelAndCurrentProviderAndModel, useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
|
import {
|
|
ModelFeatureEnum,
|
|
ModelTypeEnum,
|
|
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
|
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
|
|
import { checkHasQueryBlock } from '@/app/components/base/prompt-editor/constants'
|
|
import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list'
|
|
|
|
const useConfig = (id: string, payload: ParameterExtractorNodeType) => {
|
|
const { nodesReadOnly: readOnly } = useNodesReadOnly()
|
|
const { handleOutVarRenameChange } = useWorkflow()
|
|
const isChatMode = useIsChatMode()
|
|
|
|
const defaultConfig = useStore(s => s.nodesDefaultConfigs)[payload.type]
|
|
|
|
const [defaultRolePrefix, setDefaultRolePrefix] = useState<{ user: string; assistant: string }>({ user: '', assistant: '' })
|
|
const { inputs, setInputs: doSetInputs } = useNodeCrud<ParameterExtractorNodeType>(id, payload)
|
|
const inputRef = useRef(inputs)
|
|
|
|
const setInputs = useCallback((newInputs: ParameterExtractorNodeType) => {
|
|
if (newInputs.memory && !newInputs.memory.role_prefix) {
|
|
const newPayload = produce(newInputs, (draft) => {
|
|
draft.memory!.role_prefix = defaultRolePrefix
|
|
})
|
|
doSetInputs(newPayload)
|
|
inputRef.current = newPayload
|
|
return
|
|
}
|
|
doSetInputs(newInputs)
|
|
inputRef.current = newInputs
|
|
}, [doSetInputs, defaultRolePrefix])
|
|
|
|
const filterVar = useCallback((varPayload: Var) => {
|
|
return [VarType.string].includes(varPayload.type)
|
|
}, [])
|
|
|
|
const handleInputVarChange = useCallback((newInputVar: ValueSelector | string) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
draft.query = newInputVar as ValueSelector || []
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleExactParamsChange = useCallback((newParams: Param[], moreInfo?: MoreInfo) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
draft.parameters = newParams
|
|
})
|
|
setInputs(newInputs)
|
|
|
|
if (moreInfo && moreInfo?.type === ChangeType.changeVarName && moreInfo.payload)
|
|
handleOutVarRenameChange(id, [id, moreInfo.payload.beforeKey], [id, moreInfo.payload.afterKey!])
|
|
}, [handleOutVarRenameChange, id, inputs, setInputs])
|
|
|
|
const addExtractParameter = useCallback((payload: Param) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
if (!draft.parameters)
|
|
draft.parameters = []
|
|
draft.parameters.push(payload)
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
// model
|
|
const model = inputs.model || {
|
|
provider: '',
|
|
name: '',
|
|
mode: 'chat',
|
|
completion_params: {
|
|
temperature: 0.7,
|
|
},
|
|
}
|
|
const modelMode = inputs.model?.mode
|
|
const isChatModel = modelMode === 'chat'
|
|
|
|
const isCompletionModel = !isChatModel
|
|
|
|
const appendDefaultPromptConfig = useCallback((draft: ParameterExtractorNodeType, defaultConfig: any, _passInIsChatMode?: boolean) => {
|
|
const promptTemplates = defaultConfig.prompt_templates
|
|
if (!isChatModel) {
|
|
setDefaultRolePrefix({
|
|
user: promptTemplates.completion_model.conversation_histories_role.user_prefix,
|
|
assistant: promptTemplates.completion_model.conversation_histories_role.assistant_prefix,
|
|
})
|
|
}
|
|
}, [isChatModel])
|
|
|
|
// const [modelChanged, setModelChanged] = useState(false)
|
|
const {
|
|
currentProvider,
|
|
currentModel,
|
|
} = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.textGeneration)
|
|
|
|
const handleModelChanged = useCallback((model: { provider: string; modelId: string; mode?: string }) => {
|
|
const newInputs = produce(inputRef.current, (draft) => {
|
|
draft.model.provider = model.provider
|
|
draft.model.name = model.modelId
|
|
draft.model.mode = model.mode!
|
|
const isModeChange = model.mode !== inputRef.current.model?.mode
|
|
if (isModeChange && defaultConfig && Object.keys(defaultConfig).length > 0)
|
|
appendDefaultPromptConfig(draft, defaultConfig, model.mode === 'chat')
|
|
})
|
|
setInputs(newInputs)
|
|
// setModelChanged(true)
|
|
}, [setInputs, defaultConfig, appendDefaultPromptConfig])
|
|
|
|
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 {
|
|
currentModel: currModel,
|
|
} = useTextGenerationCurrentProviderAndModelAndModelList(
|
|
{
|
|
provider: model.provider,
|
|
model: model.name,
|
|
},
|
|
)
|
|
|
|
const isSupportFunctionCall = currModel?.features?.includes(ModelFeatureEnum.toolCall) || currModel?.features?.includes(ModelFeatureEnum.multiToolCall)
|
|
|
|
const filterInputVar = useCallback((varPayload: Var) => {
|
|
return [VarType.number, VarType.string].includes(varPayload.type)
|
|
}, [])
|
|
|
|
const {
|
|
availableVars,
|
|
availableNodesWithParent,
|
|
} = useAvailableVarList(id, {
|
|
onlyLeafNodeVar: false,
|
|
filterVar: filterInputVar,
|
|
})
|
|
|
|
const handleCompletionParamsChange = useCallback((newParams: Record<string, any>) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
draft.model.completion_params = newParams
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleInstructionChange = useCallback((newInstruction: string) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
draft.instruction = newInstruction
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const hasSetBlockStatus = {
|
|
history: false,
|
|
query: isChatMode ? checkHasQueryBlock(inputs.instruction) : false,
|
|
context: false,
|
|
}
|
|
|
|
const handleMemoryChange = useCallback((newMemory?: Memory) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
draft.memory = newMemory
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleReasoningModeChange = useCallback((newReasoningMode: ReasoningModeType) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
draft.reasoning_mode = newReasoningMode
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleImportFromTool = useCallback((params: Param[]) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
draft.parameters = params
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
// single run
|
|
const {
|
|
isShowSingleRun,
|
|
hideSingleRun,
|
|
getInputVars,
|
|
runningStatus,
|
|
handleRun,
|
|
handleStop,
|
|
runInputData,
|
|
setRunInputData,
|
|
runResult,
|
|
} = useOneStepRun<ParameterExtractorNodeType>({
|
|
id,
|
|
data: inputs,
|
|
defaultRunInputData: {
|
|
query: '',
|
|
},
|
|
})
|
|
|
|
const varInputs = getInputVars([inputs.instruction])
|
|
const inputVarValues = (() => {
|
|
const vars: Record<string, any> = {}
|
|
Object.keys(runInputData)
|
|
.forEach((key) => {
|
|
vars[key] = runInputData[key]
|
|
})
|
|
return vars
|
|
})()
|
|
|
|
const setInputVarValues = useCallback((newPayload: Record<string, any>) => {
|
|
setRunInputData(newPayload)
|
|
}, [setRunInputData])
|
|
|
|
return {
|
|
readOnly,
|
|
handleInputVarChange,
|
|
filterVar,
|
|
isChatMode,
|
|
inputs,
|
|
isChatModel,
|
|
isCompletionModel,
|
|
handleModelChanged,
|
|
handleCompletionParamsChange,
|
|
handleImportFromTool,
|
|
handleExactParamsChange,
|
|
addExtractParameter,
|
|
handleInstructionChange,
|
|
hasSetBlockStatus,
|
|
availableVars,
|
|
availableNodesWithParent,
|
|
isSupportFunctionCall,
|
|
handleReasoningModeChange,
|
|
handleMemoryChange,
|
|
varInputs,
|
|
inputVarValues,
|
|
isShowSingleRun,
|
|
hideSingleRun,
|
|
runningStatus,
|
|
handleRun,
|
|
handleStop,
|
|
runResult,
|
|
setInputVarValues,
|
|
}
|
|
}
|
|
|
|
export default useConfig
|