mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-24 07:26:47 +08:00
### What problem does this PR solve? Feat: Add memory multi-select dropdown to recall and message operator forms. #4213 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
33
web/src/components/memories-form-field.tsx
Normal file
33
web/src/components/memories-form-field.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { useFetchAllMemoryList } from '@/hooks/use-memory-request';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { RAGFlowFormItem } from './ragflow-form';
|
||||||
|
import { MultiSelect } from './ui/multi-select';
|
||||||
|
|
||||||
|
type MemoriesFormFieldProps = {
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function MemoriesFormField({ label }: MemoriesFormFieldProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const memoryList = useFetchAllMemoryList();
|
||||||
|
|
||||||
|
const options = memoryList.data?.map((memory) => ({
|
||||||
|
label: memory.name,
|
||||||
|
value: memory.id,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RAGFlowFormItem name="memory_ids" label={label}>
|
||||||
|
{(field) => (
|
||||||
|
<MultiSelect
|
||||||
|
options={options || []}
|
||||||
|
placeholder={t('common.pleaseSelect')}
|
||||||
|
maxCount={100}
|
||||||
|
onValueChange={field.onChange}
|
||||||
|
defaultValue={field.value}
|
||||||
|
modalPopover
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</RAGFlowFormItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
30
web/src/hooks/use-memory-request.ts
Normal file
30
web/src/hooks/use-memory-request.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { IMemory } from '@/interfaces/database/memory';
|
||||||
|
import memoryService from '@/services/memory-service';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
export const enum MemoryApiAction {
|
||||||
|
FetchMemoryList = 'fetchMemoryList',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useFetchAllMemoryList = () => {
|
||||||
|
const { data, isLoading, isError, refetch } = useQuery<IMemory[], Error>({
|
||||||
|
queryKey: [MemoryApiAction.FetchMemoryList],
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data: response } = await memoryService.getMemoryList(
|
||||||
|
{
|
||||||
|
params: { page_size: 100000000, page: 1 },
|
||||||
|
data: {},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
return response.data.memory_list ?? [];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
isLoading,
|
||||||
|
isError,
|
||||||
|
refetch,
|
||||||
|
};
|
||||||
|
};
|
||||||
11
web/src/interfaces/database/memory.ts
Normal file
11
web/src/interfaces/database/memory.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export interface IMemory {
|
||||||
|
avatar: null;
|
||||||
|
description: null;
|
||||||
|
id: string;
|
||||||
|
memory_type: string[];
|
||||||
|
name: string;
|
||||||
|
owner_name: string;
|
||||||
|
permissions: string;
|
||||||
|
storage_type: string;
|
||||||
|
tenant_id: string;
|
||||||
|
}
|
||||||
@ -2128,6 +2128,8 @@ Important structured information may include: names, dates, locations, events, k
|
|||||||
immediately: 'Accepted response',
|
immediately: 'Accepted response',
|
||||||
streaming: 'Final response',
|
streaming: 'Final response',
|
||||||
},
|
},
|
||||||
|
saveToMemory: 'Save to memory',
|
||||||
|
memory: 'Memory',
|
||||||
},
|
},
|
||||||
llmTools: {
|
llmTools: {
|
||||||
bad_calculator: {
|
bad_calculator: {
|
||||||
|
|||||||
@ -1940,6 +1940,8 @@ Tokenizer 会根据所选方式将内容存储为对应的数据结构。`,
|
|||||||
headerParameters: '请求头参数',
|
headerParameters: '请求头参数',
|
||||||
requestBodyParameters: '请求体参数',
|
requestBodyParameters: '请求体参数',
|
||||||
},
|
},
|
||||||
|
saveToMemory: '保存到Memory',
|
||||||
|
memory: 'Memory',
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
profile: 'All rights reserved @ React',
|
profile: 'All rights reserved @ React',
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { MemoriesFormField } from '@/components/memories-form-field';
|
||||||
import { BlockButton, Button } from '@/components/ui/button';
|
import { BlockButton, Button } from '@/components/ui/button';
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
@ -40,6 +41,7 @@ function MessageForm({ node }: INextOperatorForm) {
|
|||||||
output_format: z.string().optional(),
|
output_format: z.string().optional(),
|
||||||
auto_play: z.boolean().optional(),
|
auto_play: z.boolean().optional(),
|
||||||
status: z.number().optional(),
|
status: z.number().optional(),
|
||||||
|
memory_ids: z.array(z.string()).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
@ -159,6 +161,7 @@ function MessageForm({ node }: INextOperatorForm) {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
<MemoriesFormField label={t('flow.saveToMemory')}></MemoriesFormField>
|
||||||
</FormWrapper>
|
</FormWrapper>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -18,13 +18,13 @@ export function useShowWebhookResponseStatus(form: UseFormReturn<any>) {
|
|||||||
formData?.mode === AgentDialogueMode.Webhook &&
|
formData?.mode === AgentDialogueMode.Webhook &&
|
||||||
formData.execution_mode === WebhookExecutionMode.Streaming
|
formData.execution_mode === WebhookExecutionMode.Streaming
|
||||||
);
|
);
|
||||||
}, []);
|
}, [getNode]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (showWebhookResponseStatus && isEmpty(form.getValues('status'))) {
|
if (showWebhookResponseStatus && isEmpty(form.getValues('status'))) {
|
||||||
form.setValue('status', 200, { shouldValidate: true, shouldDirty: true });
|
form.setValue('status', 200, { shouldValidate: true, shouldDirty: true });
|
||||||
}
|
}
|
||||||
}, []);
|
}, [form, showWebhookResponseStatus]);
|
||||||
|
|
||||||
return showWebhookResponseStatus;
|
return showWebhookResponseStatus;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { Collapse } from '@/components/collapse';
|
|||||||
import { CrossLanguageFormField } from '@/components/cross-language-form-field';
|
import { CrossLanguageFormField } from '@/components/cross-language-form-field';
|
||||||
import { FormContainer } from '@/components/form-container';
|
import { FormContainer } from '@/components/form-container';
|
||||||
import { KnowledgeBaseFormField } from '@/components/knowledge-base-item';
|
import { KnowledgeBaseFormField } from '@/components/knowledge-base-item';
|
||||||
|
import { MemoriesFormField } from '@/components/memories-form-field';
|
||||||
import {
|
import {
|
||||||
MetadataFilter,
|
MetadataFilter,
|
||||||
MetadataFilterSchema,
|
MetadataFilterSchema,
|
||||||
@ -46,6 +47,7 @@ export const RetrievalPartialSchema = {
|
|||||||
use_kg: z.boolean(),
|
use_kg: z.boolean(),
|
||||||
toc_enhance: z.boolean(),
|
toc_enhance: z.boolean(),
|
||||||
...MetadataFilterSchema,
|
...MetadataFilterSchema,
|
||||||
|
memory_ids: z.array(z.string()).optional(),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FormSchema = z.object({
|
export const FormSchema = z.object({
|
||||||
@ -109,12 +111,11 @@ function RetrievalForm({ node }: INextOperatorForm) {
|
|||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<FormWrapper>
|
<FormWrapper>
|
||||||
<FormContainer>
|
<RAGFlowFormItem name="query" label={t('flow.query')}>
|
||||||
<RAGFlowFormItem name="query" label={t('flow.query')}>
|
<PromptEditor></PromptEditor>
|
||||||
<PromptEditor></PromptEditor>
|
</RAGFlowFormItem>
|
||||||
</RAGFlowFormItem>
|
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
||||||
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
<MemoriesFormField label={t('flow.memory')}></MemoriesFormField>
|
||||||
</FormContainer>
|
|
||||||
<Collapse title={<div>{t('flow.advancedSettings')}</div>}>
|
<Collapse title={<div>{t('flow.advancedSettings')}</div>}>
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<SimilaritySliderFormField
|
<SimilaritySliderFormField
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { Collapse } from '@/components/collapse';
|
|||||||
import { CrossLanguageFormField } from '@/components/cross-language-form-field';
|
import { CrossLanguageFormField } from '@/components/cross-language-form-field';
|
||||||
import { FormContainer } from '@/components/form-container';
|
import { FormContainer } from '@/components/form-container';
|
||||||
import { KnowledgeBaseFormField } from '@/components/knowledge-base-item';
|
import { KnowledgeBaseFormField } from '@/components/knowledge-base-item';
|
||||||
|
import { MemoriesFormField } from '@/components/memories-form-field';
|
||||||
import { MetadataFilter } from '@/components/metadata-filter';
|
import { MetadataFilter } from '@/components/metadata-filter';
|
||||||
import { RerankFormFields } from '@/components/rerank';
|
import { RerankFormFields } from '@/components/rerank';
|
||||||
import { SimilaritySliderFormField } from '@/components/similarity-slider';
|
import { SimilaritySliderFormField } from '@/components/similarity-slider';
|
||||||
@ -40,10 +41,9 @@ const RetrievalForm = () => {
|
|||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<FormWrapper>
|
<FormWrapper>
|
||||||
<FormContainer>
|
<DescriptionField></DescriptionField>
|
||||||
<DescriptionField></DescriptionField>
|
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
||||||
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
<MemoriesFormField label={t('flow.memory')}></MemoriesFormField>
|
||||||
</FormContainer>
|
|
||||||
<Collapse title={<div>{t('flow.advancedSettings')}</div>}>
|
<Collapse title={<div>{t('flow.advancedSettings')}</div>}>
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<SimilaritySliderFormField
|
<SimilaritySliderFormField
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
|
import request from '@/utils/next-request';
|
||||||
import { registerNextServer } from '@/utils/register-server';
|
import { registerNextServer } from '@/utils/register-server';
|
||||||
import request from '@/utils/request';
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
createMemory,
|
createMemory,
|
||||||
|
|||||||
Reference in New Issue
Block a user