Fix: Memory-related bug fixes (#12238)

### What problem does this PR solve?

Fix: Memory-related bug fixes
- Forget memory button text
- Adjust memory storage interface
### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
chanx
2025-12-26 15:56:41 +08:00
committed by GitHub
parent 3558a6c170
commit c4a66204f0
10 changed files with 56 additions and 34 deletions

View File

@ -91,13 +91,13 @@ export function ConfirmDeleteDialog({
</AlertDialogHeader> </AlertDialogHeader>
<AlertDialogFooter className="px-5 flex items-center gap-2"> <AlertDialogFooter className="px-5 flex items-center gap-2">
<AlertDialogCancel onClick={onCancel}> <AlertDialogCancel onClick={onCancel}>
{okButtonText || t('common.cancel')} {cancelButtonText || t('common.cancel')}
</AlertDialogCancel> </AlertDialogCancel>
<AlertDialogAction <AlertDialogAction
className="bg-state-error text-text-primary hover:text-text-primary hover:bg-state-error" className="bg-state-error text-text-primary hover:text-text-primary hover:bg-state-error"
onClick={onOk} onClick={onOk}
> >
{cancelButtonText || t('common.delete')} {okButtonText || t('common.delete')}
</AlertDialogAction> </AlertDialogAction>
</AlertDialogFooter> </AlertDialogFooter>
</AlertDialogContent> </AlertDialogContent>

View File

@ -112,6 +112,10 @@ export default {
Semantic Memory: General knowledge and facts about the user and world. Semantic Memory: General knowledge and facts about the user and world.
Episodic Memory: Time-stamped records of specific events and experiences. Episodic Memory: Time-stamped records of specific events and experiences.
Procedural Memory: Learned skills, habits, and automated procedures.`, Procedural Memory: Learned skills, habits, and automated procedures.`,
raw: 'raw',
semantic: 'semantic',
episodic: 'episodic',
procedural: 'procedural',
editName: 'Edit name', editName: 'Edit name',
memory: 'Memory', memory: 'Memory',
createMemory: 'Create memory', createMemory: 'Create memory',

View File

@ -99,11 +99,15 @@ export default {
llmTooltip: '分析对话内容,提取关键信息,并生成结构化的记忆摘要。', llmTooltip: '分析对话内容,提取关键信息,并生成结构化的记忆摘要。',
embeddingModelTooltip: embeddingModelTooltip:
'将文本转换为数值向量,用于语义相似度搜索和记忆检索。', '将文本转换为数值向量,用于语义相似度搜索和记忆检索。',
embeddingModelError: '记忆类型为必填项,且"原始"类型不可删除。', embeddingModelError: '记忆类型为必填项,且"row"类型不可删除。',
memoryTypeTooltip: `原始: 用户与代理之间的原始对话内容(默认必需)。 memoryTypeTooltip: `原始: 用户与代理之间的原始对话内容(默认必需)。
语义记忆: 关于用户和世界的通用知识和事实。 语义记忆: 关于用户和世界的通用知识和事实。
情景记忆: 带时间戳的特定事件和经历记录。 情景记忆: 带时间戳的特定事件和经历记录。
程序记忆: 学习的技能、习惯和自动化程序。`, 程序记忆: 学习的技能、习惯和自动化程序。`,
raw: '原始',
semantic: '语义',
episodic: '情景',
procedural: '程序',
editName: '编辑名称', editName: '编辑名称',
memory: '记忆', memory: '记忆',
createMemory: '创建记忆', createMemory: '创建记忆',

View File

@ -10,6 +10,12 @@ export enum MemoryType {
Episodic = 'episodic', Episodic = 'episodic',
Procedural = 'procedural', Procedural = 'procedural',
} }
export const MemoryOptions = (t: TFunction) => [
{ label: t('memories.raw'), value: MemoryType.Raw },
{ label: t('memories.semantic'), value: MemoryType.Semantic },
{ label: t('memories.episodic'), value: MemoryType.Episodic },
{ label: t('memories.procedural'), value: MemoryType.Procedural },
];
export const createMemoryFields = (t: TFunction) => export const createMemoryFields = (t: TFunction) =>
[ [
{ {
@ -24,12 +30,7 @@ export const createMemoryFields = (t: TFunction) =>
type: FormFieldType.MultiSelect, type: FormFieldType.MultiSelect,
placeholder: t('memories.descriptionPlaceholder'), placeholder: t('memories.descriptionPlaceholder'),
tooltip: t('memories.memoryTypeTooltip'), tooltip: t('memories.memoryTypeTooltip'),
options: [ options: MemoryOptions(t),
{ label: 'Raw', value: MemoryType.Raw },
{ label: 'Semantic', value: MemoryType.Semantic },
{ label: 'Episodic', value: MemoryType.Episodic },
{ label: 'Procedural', value: MemoryType.Procedural },
],
required: true, required: true,
customValidate: (value) => { customValidate: (value) => {
if (!value.includes(MemoryType.Raw) || !value.length) { if (!value.includes(MemoryType.Raw) || !value.length) {

View File

@ -251,6 +251,7 @@ export function MemoryTable({
title={t('memory.messages.forgetMessage')} title={t('memory.messages.forgetMessage')}
open={showDeleteDialog} open={showDeleteDialog}
onOpenChange={setShowDeleteDialog} onOpenChange={setShowDeleteDialog}
okButtonText={t('common.confirm')}
content={{ content={{
title: t('memory.messages.forgetMessageTip'), title: t('memory.messages.forgetMessageTip'),
node: ( node: (

View File

@ -95,7 +95,7 @@ export const AdvancedSettingsForm = () => {
// placeholder: t('memory.config.storageTypePlaceholder'), // placeholder: t('memory.config.storageTypePlaceholder'),
options: [ options: [
// { label: 'LRU', value: 'LRU' }, // { label: 'LRU', value: 'LRU' },
{ label: 'FIFO', value: 'FIFO' }, { label: 'FIFO', value: 'fifo' },
], ],
required: false, required: false,
}} }}

View File

@ -15,9 +15,9 @@ export const useUpdateMemoryConfig = () => {
try { try {
const params = omit(data, [ const params = omit(data, [
'id', 'id',
'memory_type', // 'memory_type',
'embd_id', // 'embd_id',
'storage_type', // 'storage_type',
]); ]);
res = await updateMemory({ res = await updateMemory({
// ...memoryDataTemp, // ...memoryDataTemp,

View File

@ -6,9 +6,9 @@ import { MainContainer } from '@/pages/dataset/dataset-setting/configuration-for
import { TopTitle } from '@/pages/dataset/dataset-title'; import { TopTitle } from '@/pages/dataset/dataset-title';
import { IMemory } from '@/pages/memories/interface'; import { IMemory } from '@/pages/memories/interface';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { t } from 'i18next';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { z } from 'zod'; import { z } from 'zod';
import { useFetchMemoryBaseConfiguration } from '../hooks/use-memory-setting'; import { useFetchMemoryBaseConfiguration } from '../hooks/use-memory-setting';
import { import {
@ -24,14 +24,15 @@ import {
memoryModelFormSchema, memoryModelFormSchema,
} from './memory-model-form'; } from './memory-model-form';
const MemoryMessageSchema = z.object({
id: z.string(),
...basicInfoSchema,
...memoryModelFormSchema,
...advancedSettingsFormSchema,
});
// type MemoryMessageForm = z.infer<typeof MemoryMessageSchema>; // type MemoryMessageForm = z.infer<typeof MemoryMessageSchema>;
export default function MemoryMessage() { export default function MemoryMessage() {
const { t } = useTranslation();
const MemoryMessageSchema = z.object({
id: z.string(),
...basicInfoSchema,
...memoryModelFormSchema(t),
...advancedSettingsFormSchema,
});
const form = useForm<IMemory>({ const form = useForm<IMemory>({
resolver: zodResolver(MemoryMessageSchema), resolver: zodResolver(MemoryMessageSchema),
defaultValues: { defaultValues: {
@ -58,11 +59,12 @@ export default function MemoryMessage() {
system_prompt: data?.system_prompt || '', system_prompt: data?.system_prompt || '',
user_prompt: data?.user_prompt || '', user_prompt: data?.user_prompt || '',
forgetting_policy: data?.forgetting_policy || 'FIFO', forgetting_policy: data?.forgetting_policy || 'FIFO',
storage_type: data?.storage_type || 'table', storage_type: data?.storage_type || 'Table',
permissions: data?.permissions || 'me', permissions: data?.permissions || 'me',
}); });
}, [data, form]); }, [data, form]);
const onSubmit = (data: IMemory) => { const onSubmit = (data: IMemory) => {
console.log('data', data);
onMemoryRenameOk(data); onMemoryRenameOk(data);
}; };
return ( return (

View File

@ -1,21 +1,30 @@
import { FormFieldType, RenderField } from '@/components/dynamic-form'; import { FormFieldType, RenderField } from '@/components/dynamic-form';
import { useModelOptions } from '@/components/llm-setting-items/llm-form-field'; import { useModelOptions } from '@/components/llm-setting-items/llm-form-field';
import { EmbeddingSelect } from '@/pages/dataset/dataset-setting/configuration/common-item'; import { EmbeddingSelect } from '@/pages/dataset/dataset-setting/configuration/common-item';
import { MemoryType } from '@/pages/memories/constants'; import { MemoryOptions, MemoryType } from '@/pages/memories/constants';
import { TFunction } from 'i18next';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { z } from 'zod'; import { z } from 'zod';
import { useFetchMemoryMessageList } from '../memory-message/hook'; import { useFetchMemoryMessageList } from '../memory-message/hook';
export const memoryModelFormSchema = { export const memoryModelFormSchema = (t: TFunction) => ({
embd_id: z.string(), embd_id: z.string(),
llm_id: z.string(), llm_id: z.string(),
memory_type: z.array(z.string()).optional(), memory_type: z.array(z.string()).superRefine((data, ctx) => {
if (!data.includes(MemoryType.Raw) || !data.length) {
ctx.addIssue({
// path: ['memory_type'],
message: t('memories.embeddingModelError'),
code: 'custom',
});
}
}),
memory_size: z.number().optional(), memory_size: z.number().optional(),
}; });
export const defaultMemoryModelForm = { export const defaultMemoryModelForm = {
embd_id: '', embd_id: '',
llm_id: '', llm_id: '',
memory_type: [MemoryType.Raw], memory_type: [],
memory_size: 0, memory_size: 0,
}; };
export const MemoryModelForm = () => { export const MemoryModelForm = () => {
@ -66,13 +75,14 @@ export const MemoryModelForm = () => {
horizontal: true, horizontal: true,
placeholder: t('memories.memoryTypePlaceholder'), placeholder: t('memories.memoryTypePlaceholder'),
tooltip: t('memories.memoryTypeTooltip'), tooltip: t('memories.memoryTypeTooltip'),
disabled: true, disabled: data?.messages?.total_count > 0,
options: [ options: MemoryOptions(t),
{ label: 'Raw', value: 'raw' }, customValidate: (value) => {
{ label: 'Semantic', value: 'semantic' }, if (!value.includes(MemoryType.Raw) || !value.length) {
{ label: 'Episodic', value: 'episodic' }, return t('memories.embeddingModelError');
{ label: 'Procedural', value: 'procedural' }, }
], return true;
},
required: true, required: true,
}} }}
/> />

View File

@ -34,7 +34,7 @@ const methods = {
} as const; } as const;
const memoryService = registerNextServer<keyof typeof methods>(methods); const memoryService = registerNextServer<keyof typeof methods>(methods);
export const updateMemoryById = (id: string, data: any) => { export const updateMemoryById = (id: string, data: any) => {
return request.put(updateMemorySetting(id), { data }); return request.put(updateMemorySetting(id), { ...data });
}; };
export const getMemoryDetailById = (id: string, data: any) => { export const getMemoryDetailById = (id: string, data: any) => {
return request.get(getMemoryDetail(id), { params: data }); return request.get(getMemoryDetail(id), { params: data });