mirror of
https://github.com/langgenius/dify.git
synced 2026-09-08 11:04:27 +08:00
feat: mermory size config
This commit is contained in:
parent
fbcc769d4e
commit
9e6940ed3e
@ -25,7 +25,7 @@ const Filed: FC<Props> = ({
|
|||||||
<div className='flex items-center h-6'>
|
<div className='flex items-center h-6'>
|
||||||
<div className='text-xs font-medium text-gray-700 uppercase'>{title}</div>
|
<div className='text-xs font-medium text-gray-700 uppercase'>{title}</div>
|
||||||
{tooltip && (
|
{tooltip && (
|
||||||
<TooltipPlus popupContent='tooltip'>
|
<TooltipPlus popupContent={tooltip}>
|
||||||
<HelpCircle className='w-3.5 h-3.5 ml-0.5 text-gray-400' />
|
<HelpCircle className='w-3.5 h-3.5 ml-0.5 text-gray-400' />
|
||||||
</TooltipPlus>
|
</TooltipPlus>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -0,0 +1,122 @@
|
|||||||
|
'use client'
|
||||||
|
import type { FC } from 'react'
|
||||||
|
import React, { useCallback } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import produce from 'immer'
|
||||||
|
import cn from 'classnames'
|
||||||
|
import type { Memory } from '../../../types'
|
||||||
|
import Field from '@/app/components/workflow/nodes/_base/components/field'
|
||||||
|
import Switch from '@/app/components/base/switch'
|
||||||
|
import Slider from '@/app/components/base/slider'
|
||||||
|
|
||||||
|
const i18nPrefix = 'workflow.nodes.common.memory'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
className?: string
|
||||||
|
readonly: boolean
|
||||||
|
payload: Memory
|
||||||
|
onChange: (memory: Memory) => void
|
||||||
|
canSetRoleName?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const WINDOW_SIZE_MIN = 1
|
||||||
|
const WINDOW_SIZE_MAX = 100
|
||||||
|
const WINDOW_SIZE_DEFAULT = 50
|
||||||
|
|
||||||
|
const MemoryConfig: FC<Props> = ({
|
||||||
|
className,
|
||||||
|
readonly,
|
||||||
|
payload,
|
||||||
|
onChange,
|
||||||
|
canSetRoleName = false,
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const handleWindowEnabledChange = useCallback((enabled: boolean) => {
|
||||||
|
const newPayload = produce(payload, (draft) => {
|
||||||
|
if (!draft.window)
|
||||||
|
draft.window = { enabled: false, size: WINDOW_SIZE_DEFAULT }
|
||||||
|
|
||||||
|
draft.window.enabled = enabled
|
||||||
|
})
|
||||||
|
onChange(newPayload)
|
||||||
|
}, [payload, onChange])
|
||||||
|
|
||||||
|
const handleWindowSizeChange = useCallback((size: number | string) => {
|
||||||
|
const newPayload = produce(payload, (draft) => {
|
||||||
|
if (!draft.window)
|
||||||
|
draft.window = { enabled: true, size: WINDOW_SIZE_DEFAULT }
|
||||||
|
let limitedSize: null | string | number = size
|
||||||
|
if (limitedSize === '') {
|
||||||
|
limitedSize = null
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
limitedSize = parseInt(limitedSize as string, 10)
|
||||||
|
if (isNaN(limitedSize))
|
||||||
|
limitedSize = WINDOW_SIZE_DEFAULT
|
||||||
|
|
||||||
|
if (limitedSize < WINDOW_SIZE_MIN)
|
||||||
|
limitedSize = WINDOW_SIZE_MIN
|
||||||
|
|
||||||
|
if (limitedSize > WINDOW_SIZE_MAX)
|
||||||
|
limitedSize = WINDOW_SIZE_MAX
|
||||||
|
}
|
||||||
|
|
||||||
|
draft.window.size = limitedSize as number
|
||||||
|
})
|
||||||
|
onChange(newPayload)
|
||||||
|
}, [payload, onChange])
|
||||||
|
|
||||||
|
const handleBlur = useCallback(() => {
|
||||||
|
if (payload.window.size === '' || payload.window.size === null)
|
||||||
|
handleWindowSizeChange(WINDOW_SIZE_DEFAULT)
|
||||||
|
}, [handleWindowSizeChange, payload.window?.size])
|
||||||
|
return (
|
||||||
|
<div className={cn(className)}>
|
||||||
|
<Field
|
||||||
|
title={t(`${i18nPrefix}.memory`)}
|
||||||
|
tooltip={t(`${i18nPrefix}.memoryTip`)!}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
{/* window size */}
|
||||||
|
<div className='flex justify-between'>
|
||||||
|
<div className='flex items-center h-8 space-x-1'>
|
||||||
|
<Switch
|
||||||
|
defaultValue={payload.window?.enabled}
|
||||||
|
onChange={handleWindowEnabledChange}
|
||||||
|
size='md'
|
||||||
|
disabled={readonly}
|
||||||
|
/>
|
||||||
|
<div className='leading-[18px] text-xs font-medium text-gray-500 uppercase'>{t(`${i18nPrefix}.windowSize`)}</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center h-8 space-x-2'>
|
||||||
|
<Slider
|
||||||
|
className='w-[144px]'
|
||||||
|
value={payload.window?.size as number}
|
||||||
|
min={WINDOW_SIZE_MIN}
|
||||||
|
max={WINDOW_SIZE_MAX}
|
||||||
|
step={1}
|
||||||
|
onChange={handleWindowSizeChange}
|
||||||
|
disabled={readonly}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
value={payload.window?.size as number}
|
||||||
|
className='shrink-0 block ml-4 pl-3 w-12 h-8 appearance-none outline-none rounded-lg bg-gray-100 text-[13px] text-gra-900'
|
||||||
|
type='number'
|
||||||
|
min={WINDOW_SIZE_MIN}
|
||||||
|
max={WINDOW_SIZE_MAX}
|
||||||
|
step={1}
|
||||||
|
onChange={e => handleWindowSizeChange(e.target.value)}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
disabled={readonly}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{canSetRoleName && (
|
||||||
|
<div>Role name</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default React.memo(MemoryConfig)
|
||||||
@ -3,25 +3,27 @@ import type { FC } from 'react'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import TextEditor from '../../_base/components/editor/text-editor'
|
import TextEditor from '../../_base/components/editor/text-editor'
|
||||||
|
import MemoryConfig from '../../_base/components/memory-config'
|
||||||
import type { Memory } from '@/app/components/workflow/types'
|
import type { Memory } from '@/app/components/workflow/types'
|
||||||
|
|
||||||
const i18nPrefix = 'workflow.nodes.questionClassifiers'
|
const i18nPrefix = 'workflow.nodes.questionClassifiers'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
instruction: string
|
instruction: string
|
||||||
onInstructionChange: (instruction: string) => void
|
onInstructionChange: (instruction: string) => void
|
||||||
memory: Memory
|
memory: Memory
|
||||||
|
onMemoryChange: (memory: Memory) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const AdvancedSetting: FC<Props> = ({
|
const AdvancedSetting: FC<Props> = ({
|
||||||
instruction,
|
instruction,
|
||||||
onInstructionChange,
|
onInstructionChange,
|
||||||
memory,
|
memory,
|
||||||
|
onMemoryChange,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<TextEditor
|
<TextEditor
|
||||||
title={t(`${i18nPrefix}.instruction`)!}
|
title={t(`${i18nPrefix}.instruction`)!}
|
||||||
value={instruction}
|
value={instruction}
|
||||||
@ -35,7 +37,14 @@ const AdvancedSetting: FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
<MemoryConfig
|
||||||
|
className='mt-4'
|
||||||
|
readonly={false}
|
||||||
|
payload={memory}
|
||||||
|
onChange={onMemoryChange}
|
||||||
|
canSetRoleName={false}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default React.memo(AdvancedSetting)
|
export default React.memo(AdvancedSetting)
|
||||||
|
|||||||
@ -20,6 +20,7 @@ const Panel: FC = () => {
|
|||||||
handleQueryVarChange,
|
handleQueryVarChange,
|
||||||
handleTopicsChange,
|
handleTopicsChange,
|
||||||
handleInstructionChange,
|
handleInstructionChange,
|
||||||
|
handleMemoryChange,
|
||||||
} = useConfig(mockData)
|
} = useConfig(mockData)
|
||||||
const model = inputs.model
|
const model = inputs.model
|
||||||
|
|
||||||
@ -65,6 +66,7 @@ const Panel: FC = () => {
|
|||||||
instruction={inputs.instruction}
|
instruction={inputs.instruction}
|
||||||
onInstructionChange={handleInstructionChange}
|
onInstructionChange={handleInstructionChange}
|
||||||
memory={inputs.memory}
|
memory={inputs.memory}
|
||||||
|
onMemoryChange={handleMemoryChange}
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useState } from 'react'
|
import { useCallback, useState } from 'react'
|
||||||
import produce from 'immer'
|
import produce from 'immer'
|
||||||
import type { ValueSelector } from '../../types'
|
import type { Memory, ValueSelector } from '../../types'
|
||||||
import type { QuestionClassifierNodeType } from './types'
|
import type { QuestionClassifierNodeType } from './types'
|
||||||
|
|
||||||
const useConfig = (initInputs: QuestionClassifierNodeType) => {
|
const useConfig = (initInputs: QuestionClassifierNodeType) => {
|
||||||
@ -44,6 +44,13 @@ const useConfig = (initInputs: QuestionClassifierNodeType) => {
|
|||||||
setInputs(newInputs)
|
setInputs(newInputs)
|
||||||
}, [inputs, setInputs])
|
}, [inputs, setInputs])
|
||||||
|
|
||||||
|
const handleMemoryChange = useCallback((memory: Memory) => {
|
||||||
|
const newInputs = produce(inputs, (draft) => {
|
||||||
|
draft.memory = memory
|
||||||
|
})
|
||||||
|
setInputs(newInputs)
|
||||||
|
}, [inputs, setInputs])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
inputs,
|
inputs,
|
||||||
handleModelChanged,
|
handleModelChanged,
|
||||||
@ -51,6 +58,7 @@ const useConfig = (initInputs: QuestionClassifierNodeType) => {
|
|||||||
handleQueryVarChange,
|
handleQueryVarChange,
|
||||||
handleTopicsChange,
|
handleTopicsChange,
|
||||||
handleInstructionChange,
|
handleInstructionChange,
|
||||||
|
handleMemoryChange,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -91,10 +91,10 @@ export enum MemoryRole {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type Memory = {
|
export type Memory = {
|
||||||
role_prefix: MemoryRole
|
role_prefix?: MemoryRole
|
||||||
window: {
|
window: {
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
size: number
|
size: number | string | null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,11 @@ const translation = {
|
|||||||
common: {
|
common: {
|
||||||
outputVars: 'Output Variables',
|
outputVars: 'Output Variables',
|
||||||
insertVarTip: 'Insert Variable',
|
insertVarTip: 'Insert Variable',
|
||||||
|
memory: {
|
||||||
|
memory: 'Memory',
|
||||||
|
memoryTip: 'Chat memory settings',
|
||||||
|
windowSize: 'Window Size',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
start: {
|
start: {
|
||||||
required: 'required',
|
required: 'required',
|
||||||
|
|||||||
@ -3,6 +3,11 @@ const translation = {
|
|||||||
common: {
|
common: {
|
||||||
outputVars: '输出变量',
|
outputVars: '输出变量',
|
||||||
insertVarTip: '插入变量',
|
insertVarTip: '插入变量',
|
||||||
|
memory: {
|
||||||
|
memory: '记忆',
|
||||||
|
memoryTip: '聊天记忆设置',
|
||||||
|
windowSize: '记忆窗口',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
start: {
|
start: {
|
||||||
required: '必填',
|
required: '必填',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user