Commit cbb298cc authored by Joel's avatar Joel

feat: config conversation role name

parent 9e6940ed
...@@ -5,11 +5,42 @@ import { useTranslation } from 'react-i18next' ...@@ -5,11 +5,42 @@ import { useTranslation } from 'react-i18next'
import produce from 'immer' import produce from 'immer'
import cn from 'classnames' import cn from 'classnames'
import type { Memory } from '../../../types' import type { Memory } from '../../../types'
import { MemoryRole } from '../../../types'
import Field from '@/app/components/workflow/nodes/_base/components/field' import Field from '@/app/components/workflow/nodes/_base/components/field'
import Switch from '@/app/components/base/switch' import Switch from '@/app/components/base/switch'
import Slider from '@/app/components/base/slider' import Slider from '@/app/components/base/slider'
const i18nPrefix = 'workflow.nodes.common.memory' const i18nPrefix = 'workflow.nodes.common.memory'
const WINDOW_SIZE_MIN = 1
const WINDOW_SIZE_MAX = 100
const WINDOW_SIZE_DEFAULT = 50
type RoleItemProps = {
readonly: boolean
title: string
value: string
onChange: (value: string) => void
}
const RoleItem: FC<RoleItemProps> = ({
readonly,
title,
value,
onChange,
}) => {
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
onChange(e.target.value)
}, [onChange])
return (
<div className='flex items-center justify-between'>
<div className='text-[13px] font-normal text-gray-700'>{title}</div>
<input
readOnly={readonly}
value={value}
onChange={handleChange}
className='w-[200px] h-8 leading-8 px-2.5 rounded-lg border-0 bg-gray-100 text-gray-900 text-[13px] placeholder:text-gray-400 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200'
type='text' />
</div>
)
}
type Props = { type Props = {
className?: string className?: string
...@@ -19,10 +50,6 @@ type Props = { ...@@ -19,10 +50,6 @@ type Props = {
canSetRoleName?: boolean canSetRoleName?: boolean
} }
const WINDOW_SIZE_MIN = 1
const WINDOW_SIZE_MAX = 100
const WINDOW_SIZE_DEFAULT = 50
const MemoryConfig: FC<Props> = ({ const MemoryConfig: FC<Props> = ({
className, className,
readonly, readonly,
...@@ -70,6 +97,21 @@ const MemoryConfig: FC<Props> = ({ ...@@ -70,6 +97,21 @@ const MemoryConfig: FC<Props> = ({
if (payload.window.size === '' || payload.window.size === null) if (payload.window.size === '' || payload.window.size === null)
handleWindowSizeChange(WINDOW_SIZE_DEFAULT) handleWindowSizeChange(WINDOW_SIZE_DEFAULT)
}, [handleWindowSizeChange, payload.window?.size]) }, [handleWindowSizeChange, payload.window?.size])
const handleRolePrefixChange = useCallback((role: MemoryRole) => {
return (value: string) => {
const newPayload = produce(payload, (draft) => {
if (!draft.role_prefix) {
draft.role_prefix = {
user: '',
assistant: '',
}
}
draft.role_prefix[role] = value
})
onChange(newPayload)
}
}, [payload, onChange])
return ( return (
<div className={cn(className)}> <div className={cn(className)}>
<Field <Field
...@@ -112,7 +154,24 @@ const MemoryConfig: FC<Props> = ({ ...@@ -112,7 +154,24 @@ const MemoryConfig: FC<Props> = ({
</div> </div>
</div> </div>
{canSetRoleName && ( {canSetRoleName && (
<div>Role name</div> <div className='mt-4'>
<div className='leading-6 text-xs font-medium text-gray-500 uppercase'>{t(`${i18nPrefix}.conversationRoleName`)}</div>
<div className='mt-1 space-y-2'>
<RoleItem
readonly={readonly}
title={t(`${i18nPrefix}.user`)}
value={payload.role_prefix?.user || ''}
onChange={handleRolePrefixChange(MemoryRole.user)}
/>
<RoleItem
readonly={readonly}
title={t(`${i18nPrefix}.assistant`)}
value={payload.role_prefix?.assistant || ''}
onChange={handleRolePrefixChange(MemoryRole.assistant)}
/>
</div>
</div>
)} )}
</> </>
</Field> </Field>
......
import { MemoryRole } from '../../types' import { BlockEnum } from '../../types'
import type { QuestionClassifierNodeType } from './types' import type { QuestionClassifierNodeType } from './types'
export const mockData: QuestionClassifierNodeType = { export const mockData: QuestionClassifierNodeType = {
title: 'Test', title: 'Test',
desc: 'Test', desc: 'Test',
type: 'Test', type: BlockEnum.QuestionClassifier,
query_variable_selector: ['aaa', 'name'], query_variable_selector: ['aaa', 'name'],
model: { model: {
provider: 'openai', provider: 'openai',
...@@ -28,7 +28,6 @@ export const mockData: QuestionClassifierNodeType = { ...@@ -28,7 +28,6 @@ export const mockData: QuestionClassifierNodeType = {
], ],
instruction: 'You are an entity extraction model that accepts an input', instruction: 'You are an entity extraction model that accepts an input',
memory: { memory: {
role_prefix: MemoryRole.assistant,
window: { window: {
enabled: false, enabled: false,
size: 0, size: 0,
......
...@@ -90,8 +90,13 @@ export enum MemoryRole { ...@@ -90,8 +90,13 @@ export enum MemoryRole {
assistant = 'assistant', assistant = 'assistant',
} }
export type RolePrefix = {
user: string
assistant: string
}
export type Memory = { export type Memory = {
role_prefix?: MemoryRole role_prefix?: RolePrefix
window: { window: {
enabled: boolean enabled: boolean
size: number | string | null size: number | string | null
......
...@@ -7,6 +7,9 @@ const translation = { ...@@ -7,6 +7,9 @@ const translation = {
memory: 'Memory', memory: 'Memory',
memoryTip: 'Chat memory settings', memoryTip: 'Chat memory settings',
windowSize: 'Window Size', windowSize: 'Window Size',
conversationRoleName: 'Conversation Role Name',
user: 'User prefix',
assistant: 'Assistant prefix',
}, },
}, },
start: { start: {
......
...@@ -7,6 +7,9 @@ const translation = { ...@@ -7,6 +7,9 @@ const translation = {
memory: '记忆', memory: '记忆',
memoryTip: '聊天记忆设置', memoryTip: '聊天记忆设置',
windowSize: '记忆窗口', windowSize: '记忆窗口',
conversationRoleName: '对话角色名',
user: '用户前缀',
assistant: '助手前缀',
}, },
}, },
start: { start: {
......
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