mirror of
https://github.com/langgenius/dify.git
synced 2026-04-20 22:28:09 +08:00
241 lines
6.6 KiB
TypeScript
241 lines
6.6 KiB
TypeScript
import type { Draft } from 'immer'
|
|
import type { MutableRefObject } from 'react'
|
|
import type { LLMNodeType } from '../types'
|
|
import type {
|
|
Memory,
|
|
PromptItem,
|
|
ValueSelector,
|
|
Var,
|
|
Variable,
|
|
} from '@/app/components/workflow/types'
|
|
import { produce } from 'immer'
|
|
import {
|
|
useCallback,
|
|
useMemo,
|
|
} from 'react'
|
|
import {
|
|
checkHasContextBlock,
|
|
checkHasHistoryBlock,
|
|
checkHasQueryBlock,
|
|
} from '@/app/components/base/prompt-editor/constants'
|
|
import {
|
|
EditionType,
|
|
VarType,
|
|
} from '@/app/components/workflow/types'
|
|
|
|
type Params = {
|
|
inputs: LLMNodeType
|
|
inputRef: MutableRefObject<LLMNodeType>
|
|
isChatMode: boolean
|
|
isChatModel: boolean
|
|
setInputs: (inputs: LLMNodeType) => void
|
|
}
|
|
|
|
const createPromptConfig = () => ({
|
|
jinja2_variables: [] as Variable[],
|
|
})
|
|
|
|
const ensurePromptConfig = (draft: Draft<LLMNodeType>): { jinja2_variables: Variable[] } => {
|
|
if (!draft.prompt_config)
|
|
draft.prompt_config = createPromptConfig()
|
|
|
|
if (!draft.prompt_config.jinja2_variables)
|
|
draft.prompt_config.jinja2_variables = []
|
|
|
|
return draft.prompt_config as { jinja2_variables: Variable[] }
|
|
}
|
|
|
|
const filterInputVar = (varPayload: Var) => {
|
|
return [
|
|
VarType.number,
|
|
VarType.string,
|
|
VarType.secret,
|
|
VarType.arrayString,
|
|
VarType.arrayNumber,
|
|
VarType.file,
|
|
VarType.arrayFile,
|
|
].includes(varPayload.type)
|
|
}
|
|
|
|
const filterJinja2InputVar = (varPayload: Var) => {
|
|
return [
|
|
VarType.number,
|
|
VarType.string,
|
|
VarType.secret,
|
|
VarType.arrayString,
|
|
VarType.arrayNumber,
|
|
VarType.arrayBoolean,
|
|
VarType.arrayObject,
|
|
VarType.object,
|
|
VarType.array,
|
|
VarType.boolean,
|
|
].includes(varPayload.type)
|
|
}
|
|
|
|
const filterMemoryPromptVar = (varPayload: Var) => {
|
|
return [
|
|
VarType.arrayObject,
|
|
VarType.array,
|
|
VarType.number,
|
|
VarType.string,
|
|
VarType.secret,
|
|
VarType.arrayString,
|
|
VarType.arrayNumber,
|
|
VarType.file,
|
|
VarType.arrayFile,
|
|
].includes(varPayload.type)
|
|
}
|
|
|
|
const useLLMPromptConfig = ({
|
|
inputs,
|
|
inputRef,
|
|
isChatMode,
|
|
isChatModel,
|
|
setInputs,
|
|
}: Params) => {
|
|
const hasSetBlockStatus = useMemo(() => {
|
|
const promptTemplate = inputs.prompt_template
|
|
const hasSetContext = isChatModel
|
|
? (promptTemplate as PromptItem[]).some(item => checkHasContextBlock(item.text))
|
|
: checkHasContextBlock((promptTemplate as PromptItem).text)
|
|
|
|
if (!isChatMode) {
|
|
return {
|
|
history: false,
|
|
query: false,
|
|
context: hasSetContext,
|
|
}
|
|
}
|
|
|
|
if (isChatModel) {
|
|
return {
|
|
history: false,
|
|
query: (promptTemplate as PromptItem[]).some(item => checkHasQueryBlock(item.text)),
|
|
context: hasSetContext,
|
|
}
|
|
}
|
|
|
|
return {
|
|
history: checkHasHistoryBlock((promptTemplate as PromptItem).text),
|
|
query: checkHasQueryBlock((promptTemplate as PromptItem).text),
|
|
context: hasSetContext,
|
|
}
|
|
}, [inputs.prompt_template, isChatMode, isChatModel])
|
|
|
|
const shouldShowContextTip = !hasSetBlockStatus.context && inputs.context.enabled
|
|
|
|
const isShowVars = useMemo(() => {
|
|
if (isChatModel)
|
|
return (inputs.prompt_template as PromptItem[]).some(item => item.edition_type === EditionType.jinja2)
|
|
|
|
return (inputs.prompt_template as PromptItem).edition_type === EditionType.jinja2
|
|
}, [inputs.prompt_template, isChatModel])
|
|
|
|
const handleAddEmptyVariable = useCallback(() => {
|
|
const nextInputs = produce(inputRef.current, (draft) => {
|
|
const promptConfig = ensurePromptConfig(draft)
|
|
promptConfig.jinja2_variables.push({
|
|
variable: '',
|
|
value_selector: [],
|
|
})
|
|
})
|
|
setInputs(nextInputs)
|
|
}, [inputRef, setInputs])
|
|
|
|
const handleAddVariable = useCallback((payload: Variable) => {
|
|
const nextInputs = produce(inputRef.current, (draft) => {
|
|
const promptConfig = ensurePromptConfig(draft)
|
|
promptConfig.jinja2_variables.push(payload)
|
|
})
|
|
setInputs(nextInputs)
|
|
}, [inputRef, setInputs])
|
|
|
|
const handleVarListChange = useCallback((newList: Variable[]) => {
|
|
const nextInputs = produce(inputRef.current, (draft) => {
|
|
const promptConfig = ensurePromptConfig(draft)
|
|
promptConfig.jinja2_variables = newList
|
|
})
|
|
setInputs(nextInputs)
|
|
}, [inputRef, setInputs])
|
|
|
|
const handleVarNameChange = useCallback((oldName: string, newName: string) => {
|
|
const nextInputs = produce(inputRef.current, (draft) => {
|
|
if (isChatModel) {
|
|
const promptTemplate = draft.prompt_template as PromptItem[]
|
|
promptTemplate
|
|
.filter(item => item.edition_type === EditionType.jinja2)
|
|
.forEach((item) => {
|
|
item.jinja2_text = (item.jinja2_text || '').replaceAll(`{{ ${oldName} }}`, `{{ ${newName} }}`)
|
|
})
|
|
return
|
|
}
|
|
|
|
const promptTemplate = draft.prompt_template as PromptItem
|
|
if (promptTemplate.edition_type !== EditionType.jinja2)
|
|
return
|
|
|
|
promptTemplate.jinja2_text = (promptTemplate.jinja2_text || '').replaceAll(`{{ ${oldName} }}`, `{{ ${newName} }}`)
|
|
})
|
|
setInputs(nextInputs)
|
|
}, [inputRef, isChatModel, setInputs])
|
|
|
|
const handleContextVarChange = useCallback((newVar: ValueSelector | string) => {
|
|
const nextInputs = produce(inputRef.current, (draft) => {
|
|
draft.context.variable_selector = (newVar as ValueSelector) || []
|
|
draft.context.enabled = !!(newVar && newVar.length > 0)
|
|
})
|
|
setInputs(nextInputs)
|
|
}, [inputRef, setInputs])
|
|
|
|
const handlePromptChange = useCallback((newPrompt: PromptItem[] | PromptItem) => {
|
|
const nextInputs = produce(inputRef.current, (draft) => {
|
|
draft.prompt_template = newPrompt
|
|
})
|
|
setInputs(nextInputs)
|
|
}, [inputRef, setInputs])
|
|
|
|
const handleMemoryChange = useCallback((newMemory?: Memory) => {
|
|
const nextInputs = produce(inputRef.current, (draft) => {
|
|
draft.memory = newMemory
|
|
})
|
|
setInputs(nextInputs)
|
|
}, [inputRef, setInputs])
|
|
|
|
const handleSyeQueryChange = useCallback((newQuery: string) => {
|
|
const nextInputs = produce(inputRef.current, (draft) => {
|
|
if (!draft.memory) {
|
|
draft.memory = {
|
|
window: {
|
|
enabled: false,
|
|
size: 10,
|
|
},
|
|
query_prompt_template: newQuery,
|
|
}
|
|
return
|
|
}
|
|
|
|
draft.memory.query_prompt_template = newQuery
|
|
})
|
|
setInputs(nextInputs)
|
|
}, [inputRef, setInputs])
|
|
|
|
return {
|
|
hasSetBlockStatus,
|
|
shouldShowContextTip,
|
|
isShowVars,
|
|
handleAddEmptyVariable,
|
|
handleAddVariable,
|
|
handleVarListChange,
|
|
handleVarNameChange,
|
|
handleContextVarChange,
|
|
handlePromptChange,
|
|
handleMemoryChange,
|
|
handleSyeQueryChange,
|
|
filterInputVar,
|
|
filterJinja2InputVar,
|
|
filterVar: filterMemoryPromptVar,
|
|
}
|
|
}
|
|
|
|
export default useLLMPromptConfig
|