Feat: On the agent page and chat page, you can only select knowledge bases that use the same embedding model. #12320 (#12321)

### What problem does this PR solve?

Feat: On the agent page and chat page, you can only select knowledge
bases that use the same embedding model. #12320

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-12-30 17:08:30 +08:00
committed by GitHub
parent ff2c70608d
commit 109e782493

View File

@ -1,79 +1,72 @@
import { DocumentParserType } from '@/constants/knowledge';
import { useTranslate } from '@/hooks/common-hooks';
import { useFetchKnowledgeList } from '@/hooks/use-knowledge-request';
import { IKnowledge } from '@/interfaces/database/knowledge';
import { useBuildQueryVariableOptions } from '@/pages/agent/hooks/use-get-begin-query';
import { UserOutlined } from '@ant-design/icons';
import { Avatar as AntAvatar, Form, Select, Space } from 'antd';
import { toLower } from 'lodash';
import { useMemo } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { RAGFlowAvatar } from './ragflow-avatar';
import { FormControl, FormField, FormItem, FormLabel } from './ui/form';
import { MultiSelect } from './ui/multi-select';
interface KnowledgeBaseItemProps {
label?: string;
tooltipText?: string;
name?: string;
required?: boolean;
onChange?(): void;
}
const KnowledgeBaseItem = ({
label,
tooltipText,
name,
required = true,
onChange,
}: KnowledgeBaseItemProps) => {
const { t } = useTranslate('chat');
const { list: knowledgeList } = useFetchKnowledgeList(true);
const filteredKnowledgeList = knowledgeList.filter(
(x) => x.parser_id !== DocumentParserType.Tag,
);
const knowledgeOptions = filteredKnowledgeList.map((x) => ({
label: (
<Space>
<AntAvatar size={20} icon={<UserOutlined />} src={x.avatar} />
{x.name}
</Space>
),
value: x.id,
}));
return (
<Form.Item
label={label || t('knowledgeBases')}
name={name || 'kb_ids'}
tooltip={tooltipText || t('knowledgeBasesTip')}
rules={[
{
required,
message: t('knowledgeBasesMessage'),
type: 'array',
},
]}
>
<Select
mode="multiple"
options={knowledgeOptions}
placeholder={t('knowledgeBasesMessage')}
onChange={onChange}
></Select>
</Form.Item>
);
};
export default KnowledgeBaseItem;
import { MultiSelect, MultiSelectOptionType } from './ui/multi-select';
function buildQueryVariableOptionsByShowVariable(showVariable?: boolean) {
return showVariable ? useBuildQueryVariableOptions : () => [];
}
export function useDisableDifferenceEmbeddingDataset() {
const [datasetOptions, setDatasetOptions] = useState<MultiSelectOptionType[]>(
[],
);
const [datasetSelectEmbedId, setDatasetSelectEmbedId] = useState('');
const { list: datasetListOrigin } = useFetchKnowledgeList(true);
useEffect(() => {
const datasetListMap = datasetListOrigin
.filter((x) => x.parser_id !== DocumentParserType.Tag)
.map((item: IKnowledge) => {
return {
label: item.name,
icon: () => (
<RAGFlowAvatar
className="size-4"
avatar={item.avatar}
name={item.name}
/>
),
suffix: (
<div className="text-xs px-4 p-1 bg-bg-card text-text-secondary rounded-lg border border-bg-card">
{item.embd_id}
</div>
),
value: item.id,
disabled:
item.embd_id !== datasetSelectEmbedId &&
datasetSelectEmbedId !== '',
};
});
setDatasetOptions(datasetListMap);
}, [datasetListOrigin, datasetSelectEmbedId]);
const handleDatasetSelectChange = (
value: string[],
onChange: (value: string[]) => void,
) => {
if (value.length) {
const data = datasetListOrigin?.find((item) => item.id === value[0]);
setDatasetSelectEmbedId(data?.embd_id ?? '');
} else {
setDatasetSelectEmbedId('');
}
onChange?.(value);
};
return {
datasetOptions,
handleDatasetSelectChange,
};
}
export function KnowledgeBaseFormField({
showVariable = false,
}: {
@ -82,22 +75,12 @@ export function KnowledgeBaseFormField({
const form = useFormContext();
const { t } = useTranslation();
const { list: knowledgeList } = useFetchKnowledgeList(true);
const filteredKnowledgeList = knowledgeList.filter(
(x) => x.parser_id !== DocumentParserType.Tag,
);
const { datasetOptions, handleDatasetSelectChange } =
useDisableDifferenceEmbeddingDataset();
const nextOptions = buildQueryVariableOptionsByShowVariable(showVariable)();
const knowledgeOptions = filteredKnowledgeList.map((x) => ({
label: x.name,
value: x.id,
icon: () => (
<RAGFlowAvatar className="size-4 mr-2" avatar={x.avatar} name={x.name} />
),
}));
const knowledgeOptions = datasetOptions;
const options = useMemo(() => {
if (showVariable) {
return [
@ -140,11 +123,14 @@ export function KnowledgeBaseFormField({
<FormControl>
<MultiSelect
options={options}
onValueChange={field.onChange}
onValueChange={(value) => {
handleDatasetSelectChange(value, field.onChange);
}}
placeholder={t('chat.knowledgeBasesMessage')}
variant="inverted"
maxCount={100}
defaultValue={field.value}
showSelectAll={false}
{...field}
/>
</FormControl>