Feature:memory function complete (#11982)

### What problem does this PR solve?

memory function complete

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
chanx
2025-12-17 12:35:26 +08:00
committed by GitHub
parent 2595644dfd
commit 205a6483f5
20 changed files with 226 additions and 142 deletions

View File

@ -1,9 +1,9 @@
import { DynamicForm, DynamicFormRef } from '@/components/dynamic-form';
import { DynamicForm } from '@/components/dynamic-form';
import { useModelOptions } from '@/components/llm-setting-items/llm-form-field';
import { HomeIcon } from '@/components/svg-icon';
import { Modal } from '@/components/ui/modal/modal';
import { t } from 'i18next';
import { memo, useCallback, useMemo, useState } from 'react';
import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { createMemoryFields } from './constants';
import { IMemory } from './interface';
@ -17,21 +17,16 @@ type IProps = {
};
export const AddOrEditModal = memo((props: IProps) => {
const { open, onClose, onSubmit, initialMemory, isCreate } = props;
const [formInstance, setFormInstance] = useState<DynamicFormRef | null>(null);
const formCallbackRef = useCallback((node: DynamicFormRef | null) => {
if (node) {
// formRef.current = node;
setFormInstance(node);
}
}, []);
const { t } = useTranslation();
const { modelOptions } = useModelOptions();
const fields = useMemo(() => {
if (!isCreate) {
return createMemoryFields.filter((field: any) => field.name === 'name');
return createMemoryFields(t).filter(
(field: any) => field.name === 'name',
);
} else {
const tempFields = createMemoryFields.map((field: any) => {
const tempFields = createMemoryFields(t).map((field: any) => {
if (field.name === 'llm_id') {
return {
...field,
@ -57,14 +52,13 @@ export const AddOrEditModal = memo((props: IProps) => {
<div>
<HomeIcon name="memory" width={'24'} />
</div>
{t('memories.createMemory')}
{isCreate ? t('memories.createMemory') : t('memories.editName')}
</div>
}
showfooter={false}
confirmLoading={props.loading}
>
<DynamicForm.Root
ref={formCallbackRef}
fields={fields}
onSubmit={() => {}}
defaultValues={initialMemory}

View File

@ -1,41 +1,63 @@
import { FormFieldConfig, FormFieldType } from '@/components/dynamic-form';
import { EmbeddingSelect } from '@/pages/dataset/dataset-setting/configuration/common-item';
import { t } from 'i18next';
import { TFunction } from 'i18next';
export enum MemoryType {
Raw = 'raw',
Semantic = 'semantic',
Episodic = 'episodic',
Procedural = 'procedural',
}
export const createMemoryFields = (t: TFunction) =>
[
{
name: 'name',
label: t('memories.name'),
placeholder: t('memories.memoryNamePlaceholder'),
required: true,
},
{
name: 'memory_type',
label: t('memories.memoryType'),
type: FormFieldType.MultiSelect,
placeholder: t('memories.descriptionPlaceholder'),
tooltip: t('memories.memoryTypeTooltip'),
options: [
{ label: 'Raw', value: MemoryType.Raw },
{ label: 'Semantic', value: MemoryType.Semantic },
{ label: 'Episodic', value: MemoryType.Episodic },
{ label: 'Procedural', value: MemoryType.Procedural },
],
required: true,
customValidate: (value) => {
if (!value.includes(MemoryType.Raw) || !value.length) {
return t('memories.embeddingModelError');
}
return true;
},
},
{
name: 'embd_id',
label: t('memories.embeddingModel'),
placeholder: t('memories.selectModel'),
tooltip: t('memories.embeddingModelTooltip'),
required: true,
// hideLabel: true,
// type: 'custom',
render: (field) => <EmbeddingSelect field={field} isEdit={false} />,
},
{
name: 'llm_id',
label: t('memories.llm'),
placeholder: t('memories.selectModel'),
required: true,
type: FormFieldType.Select,
tooltip: t('memories.llmTooltip'),
},
] as FormFieldConfig[];
export const createMemoryFields = [
{
name: 'name',
label: t('memories.name'),
placeholder: t('memories.memoryNamePlaceholder'),
required: true,
},
{
name: 'memory_type',
label: t('memories.memoryType'),
type: FormFieldType.MultiSelect,
placeholder: t('memories.descriptionPlaceholder'),
options: [
{ label: 'Raw', value: 'raw' },
{ label: 'Semantic', value: 'semantic' },
{ label: 'Episodic', value: 'episodic' },
{ label: 'Procedural', value: 'procedural' },
],
required: true,
},
{
name: 'embd_id',
label: t('memories.embeddingModel'),
placeholder: t('memories.selectModel'),
required: true,
// hideLabel: true,
// type: 'custom',
render: (field) => <EmbeddingSelect field={field} isEdit={false} />,
},
{
name: 'llm_id',
label: t('memories.llm'),
placeholder: t('memories.selectModel'),
required: true,
type: FormFieldType.Select,
},
] as FormFieldConfig[];
export const defaultMemoryFields = {
name: '',
memory_type: [MemoryType.Raw],
embd_id: '',
llm_id: '',
};

View File

@ -74,12 +74,12 @@ export const useFetchMemoryList = () => {
queryFn: async () => {
const { data: response } = await memoryService.getMemoryList(
{
data: {
params: {
keywords: debouncedSearchString,
page_size: pagination.pageSize,
page: pagination.current,
},
params: {},
data: {},
},
true,
);
@ -197,6 +197,7 @@ export const useUpdateMemory = () => {
if (response.code !== 0) {
throw new Error(response.message || 'Failed to update memory');
}
return response.data;
},
onSuccess: (data, variables) => {

View File

@ -10,8 +10,9 @@ import { Plus } from 'lucide-react';
import { useCallback, useEffect, useState } from 'react';
import { useSearchParams } from 'umi';
import { AddOrEditModal } from './add-or-edit-modal';
import { defaultMemoryFields } from './constants';
import { useFetchMemoryList, useRenameMemory } from './hooks';
import { ICreateMemoryProps } from './interface';
import { ICreateMemoryProps, IMemory } from './interface';
import { MemoryCard } from './memory-card';
export default function MemoryList() {
@ -45,7 +46,7 @@ export default function MemoryList() {
const openCreateModalFun = useCallback(() => {
// setIsEdit(false);
setAddOrEditType('add');
showMemoryRenameModal();
showMemoryRenameModal(defaultMemoryFields as unknown as IMemory);
}, [showMemoryRenameModal]);
const handlePageChange = useCallback(
(page: number, pageSize?: number) => {
@ -131,12 +132,12 @@ export default function MemoryList() {
})}
</CardContainer>
</div>
{list?.data.total && list?.data.total > 0 && (
{list?.data.total_count && list?.data.total_count > 0 && (
<div className="px-8 mb-4">
<RAGFlowPagination
{...pick(pagination, 'current', 'pageSize')}
// total={pagination.total}
total={list?.data.total}
total={list?.data.total_count}
onChange={handlePageChange}
/>
</div>

View File

@ -36,12 +36,14 @@ export interface IMemory extends ICreateMemoryProps {
temperature: string;
system_prompt: string;
user_prompt: string;
create_date: string;
create_time: number;
}
export interface MemoryListResponse {
code: number;
data: {
memory_list: Array<IMemory>;
total: number;
total_count: number;
};
message: string;
}

View File

@ -17,6 +17,7 @@ export function MemoryCard({ data, showMemoryRenameModal }: IProps) {
name: data?.name,
avatar: data?.avatar,
description: data?.description,
update_time: data?.create_time,
}}
moreDropdown={
<MemoryDropdown