Commit 9e6940ed authored by Joel's avatar Joel

feat: mermory size config

parent fbcc769d
...@@ -25,7 +25,7 @@ const Filed: FC<Props> = ({ ...@@ -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>
)} )}
......
'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' ...@@ -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> = ({ ...@@ -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 = () => { ...@@ -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 = () => { ...@@ -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>
......
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) => { ...@@ -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) => { ...@@ -51,6 +58,7 @@ const useConfig = (initInputs: QuestionClassifierNodeType) => {
handleQueryVarChange, handleQueryVarChange,
handleTopicsChange, handleTopicsChange,
handleInstructionChange, handleInstructionChange,
handleMemoryChange,
} }
} }
......
...@@ -91,10 +91,10 @@ export enum MemoryRole { ...@@ -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 = { ...@@ -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 = { ...@@ -3,6 +3,11 @@ const translation = {
common: { common: {
outputVars: '输出变量', outputVars: '输出变量',
insertVarTip: '插入变量', insertVarTip: '插入变量',
memory: {
memory: '记忆',
memoryTip: '聊天记忆设置',
windowSize: '记忆窗口',
},
}, },
start: { start: {
required: '必填', required: '必填',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment