mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-14 04:36:01 +08:00
### What problem does this PR solve? Feat: Rendering recall test page #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
d73a08b9eb
commit
bfaa469b9a
@ -19,7 +19,7 @@ interface IProps {
|
|||||||
leftPanel?: ReactNode;
|
leftPanel?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilterButton = React.forwardRef<
|
export const FilterButton = React.forwardRef<
|
||||||
HTMLButtonElement,
|
HTMLButtonElement,
|
||||||
ButtonProps & { count?: number }
|
ButtonProps & { count?: number }
|
||||||
>(({ count = 0, ...props }, ref) => {
|
>(({ count = 0, ...props }, ref) => {
|
||||||
|
@ -4,7 +4,8 @@ import { useSelectLlmOptionsByModelType } from '@/hooks/llm-hooks';
|
|||||||
import { Select as AntSelect, Form, message, Slider } from 'antd';
|
import { Select as AntSelect, Form, message, Slider } from 'antd';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { useFormContext } from 'react-hook-form';
|
||||||
import { SingleFormSlider } from './ui/dual-range-slider';
|
import { z } from 'zod';
|
||||||
|
import { SliderInputFormField } from './slider-input-form-field';
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormField,
|
FormField,
|
||||||
@ -63,6 +64,14 @@ export const RerankItem = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const topKSchema = {
|
||||||
|
top_k: z.number().optional(),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const initialTopKValue = {
|
||||||
|
top_k: 1024,
|
||||||
|
};
|
||||||
|
|
||||||
const Rerank = () => {
|
const Rerank = () => {
|
||||||
const { t } = useTranslate('knowledgeDetails');
|
const { t } = useTranslate('knowledgeDetails');
|
||||||
|
|
||||||
@ -143,7 +152,7 @@ function RerankFormField() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function RerankFormFields() {
|
export function RerankFormFields() {
|
||||||
const { control, watch } = useFormContext();
|
const { watch } = useFormContext();
|
||||||
const { t } = useTranslate('knowledgeDetails');
|
const { t } = useTranslate('knowledgeDetails');
|
||||||
const rerankId = watch(RerankId);
|
const rerankId = watch(RerankId);
|
||||||
|
|
||||||
@ -151,23 +160,13 @@ export function RerankFormFields() {
|
|||||||
<>
|
<>
|
||||||
<RerankFormField></RerankFormField>
|
<RerankFormField></RerankFormField>
|
||||||
{rerankId && (
|
{rerankId && (
|
||||||
<FormField
|
<SliderInputFormField
|
||||||
control={control}
|
|
||||||
name={'top_k'}
|
name={'top_k'}
|
||||||
render={({ field }) => (
|
label={t('topK')}
|
||||||
<FormItem>
|
max={2048}
|
||||||
<FormLabel tooltip={t('topKTip')}>{t('topK')}</FormLabel>
|
min={1}
|
||||||
<FormControl>
|
tooltip={t('topKTip')}
|
||||||
<SingleFormSlider
|
></SliderInputFormField>
|
||||||
{...field}
|
|
||||||
max={2048}
|
|
||||||
min={1}
|
|
||||||
></SingleFormSlider>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,15 +1,7 @@
|
|||||||
import { useTranslate } from '@/hooks/common-hooks';
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
import { Form, Slider } from 'antd';
|
import { Form, Slider } from 'antd';
|
||||||
import { useFormContext } from 'react-hook-form';
|
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { SingleFormSlider } from '../ui/dual-range-slider';
|
import { SliderInputFormField } from '../slider-input-form-field';
|
||||||
import {
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '../ui/form';
|
|
||||||
|
|
||||||
type FieldType = {
|
type FieldType = {
|
||||||
similarity_threshold?: number;
|
similarity_threshold?: number;
|
||||||
@ -73,51 +65,24 @@ export function SimilaritySliderFormField({
|
|||||||
vectorSimilarityWeightName = 'vector_similarity_weight',
|
vectorSimilarityWeightName = 'vector_similarity_weight',
|
||||||
isTooltipShown,
|
isTooltipShown,
|
||||||
}: SimilaritySliderFormFieldProps) {
|
}: SimilaritySliderFormFieldProps) {
|
||||||
const form = useFormContext();
|
|
||||||
const { t } = useTranslate('knowledgeDetails');
|
const { t } = useTranslate('knowledgeDetails');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FormField
|
<SliderInputFormField
|
||||||
control={form.control}
|
|
||||||
name={'similarity_threshold'}
|
name={'similarity_threshold'}
|
||||||
render={({ field }) => (
|
label={t('similarityThreshold')}
|
||||||
<FormItem>
|
max={1}
|
||||||
<FormLabel tooltip={isTooltipShown && t('similarityThresholdTip')}>
|
step={0.01}
|
||||||
{t('similarityThreshold')}
|
tooltip={isTooltipShown && t('similarityThresholdTip')}
|
||||||
</FormLabel>
|
></SliderInputFormField>
|
||||||
<FormControl>
|
<SliderInputFormField
|
||||||
<SingleFormSlider
|
|
||||||
{...field}
|
|
||||||
max={1}
|
|
||||||
step={0.01}
|
|
||||||
></SingleFormSlider>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name={vectorSimilarityWeightName}
|
name={vectorSimilarityWeightName}
|
||||||
render={({ field }) => (
|
label={t('vectorSimilarityWeight')}
|
||||||
<FormItem>
|
max={1}
|
||||||
<FormLabel
|
step={0.01}
|
||||||
tooltip={isTooltipShown && t('vectorSimilarityWeightTip')}
|
tooltip={isTooltipShown && t('vectorSimilarityWeightTip')}
|
||||||
>
|
></SliderInputFormField>
|
||||||
{t('vectorSimilarityWeight')}
|
|
||||||
</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<SingleFormSlider
|
|
||||||
{...field}
|
|
||||||
max={1}
|
|
||||||
step={0.01}
|
|
||||||
></SingleFormSlider>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { cn } from '@/lib/utils';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { useFormContext } from 'react-hook-form';
|
||||||
import { SingleFormSlider } from './ui/dual-range-slider';
|
import { SingleFormSlider } from './ui/dual-range-slider';
|
||||||
@ -18,6 +19,7 @@ type SliderInputFormFieldProps = {
|
|||||||
label: string;
|
label: string;
|
||||||
tooltip?: ReactNode;
|
tooltip?: ReactNode;
|
||||||
defaultValue?: number;
|
defaultValue?: number;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function SliderInputFormField({
|
export function SliderInputFormField({
|
||||||
@ -28,6 +30,7 @@ export function SliderInputFormField({
|
|||||||
name,
|
name,
|
||||||
tooltip,
|
tooltip,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
|
className,
|
||||||
}: SliderInputFormFieldProps) {
|
}: SliderInputFormFieldProps) {
|
||||||
const form = useFormContext();
|
const form = useFormContext();
|
||||||
|
|
||||||
@ -39,7 +42,12 @@ export function SliderInputFormField({
|
|||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel tooltip={tooltip}>{label}</FormLabel>
|
<FormLabel tooltip={tooltip}>{label}</FormLabel>
|
||||||
<div className="flex items-center gap-14 justify-between">
|
<div
|
||||||
|
className={cn(
|
||||||
|
'flex items-center gap-14 justify-between',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<SingleFormSlider
|
<SingleFormSlider
|
||||||
{...field}
|
{...field}
|
||||||
|
@ -10,13 +10,12 @@ import kbService, { listDataset } from '@/services/knowledge-service';
|
|||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { useDebounce } from 'ahooks';
|
import { useDebounce } from 'ahooks';
|
||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useParams } from 'umi';
|
import { useParams } from 'umi';
|
||||||
import {
|
import {
|
||||||
useGetPaginationWithRouter,
|
useGetPaginationWithRouter,
|
||||||
useHandleSearchChange,
|
useHandleSearchChange,
|
||||||
} from './logic-hooks';
|
} from './logic-hooks';
|
||||||
import { useSetPaginationParams } from './route-hook';
|
|
||||||
|
|
||||||
export const enum KnowledgeApiAction {
|
export const enum KnowledgeApiAction {
|
||||||
TestRetrieval = 'testRetrieval',
|
TestRetrieval = 'testRetrieval',
|
||||||
@ -35,8 +34,17 @@ export const useKnowledgeBaseId = () => {
|
|||||||
|
|
||||||
export const useTestRetrieval = () => {
|
export const useTestRetrieval = () => {
|
||||||
const knowledgeBaseId = useKnowledgeBaseId();
|
const knowledgeBaseId = useKnowledgeBaseId();
|
||||||
const { page, size: pageSize } = useSetPaginationParams();
|
|
||||||
const [values, setValues] = useState<ITestRetrievalRequestBody>();
|
const [values, setValues] = useState<ITestRetrievalRequestBody>();
|
||||||
|
const mountedRef = useRef(false);
|
||||||
|
const { filterValue, handleFilterSubmit } = useHandleFilterSubmit();
|
||||||
|
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const [pageSize, setPageSize] = useState(10);
|
||||||
|
|
||||||
|
const onPaginationChange = useCallback((page: number, pageSize: number) => {
|
||||||
|
setPage(page);
|
||||||
|
setPageSize(pageSize);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const queryParams = useMemo(() => {
|
const queryParams = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
@ -44,15 +52,16 @@ export const useTestRetrieval = () => {
|
|||||||
kb_id: values?.kb_id || knowledgeBaseId,
|
kb_id: values?.kb_id || knowledgeBaseId,
|
||||||
page,
|
page,
|
||||||
size: pageSize,
|
size: pageSize,
|
||||||
|
doc_ids: filterValue.doc_ids,
|
||||||
};
|
};
|
||||||
}, [knowledgeBaseId, page, pageSize, values]);
|
}, [filterValue, knowledgeBaseId, page, pageSize, values]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
isFetching: loading,
|
isFetching: loading,
|
||||||
refetch,
|
refetch,
|
||||||
} = useQuery<INextTestingResult>({
|
} = useQuery<INextTestingResult>({
|
||||||
queryKey: [KnowledgeApiAction.TestRetrieval, queryParams],
|
queryKey: [KnowledgeApiAction.TestRetrieval, queryParams, page, pageSize],
|
||||||
initialData: {
|
initialData: {
|
||||||
chunks: [],
|
chunks: [],
|
||||||
doc_aggs: [],
|
doc_aggs: [],
|
||||||
@ -62,12 +71,27 @@ export const useTestRetrieval = () => {
|
|||||||
gcTime: 0,
|
gcTime: 0,
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data } = await kbService.retrieval_test(queryParams);
|
const { data } = await kbService.retrieval_test(queryParams);
|
||||||
console.log('🚀 ~ queryFn: ~ data:', data);
|
|
||||||
return data?.data ?? {};
|
return data?.data ?? {};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return { data, loading, setValues, refetch };
|
useEffect(() => {
|
||||||
|
if (mountedRef.current) {
|
||||||
|
refetch();
|
||||||
|
}
|
||||||
|
mountedRef.current = true;
|
||||||
|
}, [page, pageSize, refetch, filterValue]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
loading,
|
||||||
|
setValues,
|
||||||
|
refetch,
|
||||||
|
onPaginationChange,
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
handleFilterSubmit,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useFetchNextKnowledgeListByPage = () => {
|
export const useFetchNextKnowledgeListByPage = () => {
|
||||||
|
@ -50,7 +50,8 @@ const MarkdownContent = ({
|
|||||||
const { setDocumentIds, data: fileThumbnails } =
|
const { setDocumentIds, data: fileThumbnails } =
|
||||||
useFetchDocumentThumbnailsByIds();
|
useFetchDocumentThumbnailsByIds();
|
||||||
const contentWithCursor = useMemo(() => {
|
const contentWithCursor = useMemo(() => {
|
||||||
let text = DOMPurify.sanitize(content);
|
// let text = DOMPurify.sanitize(content);
|
||||||
|
let text = content;
|
||||||
if (text === '') {
|
if (text === '') {
|
||||||
text = t('chat.searching');
|
text = t('chat.searching');
|
||||||
}
|
}
|
||||||
|
15
web/src/pages/dataset/dataset-title.tsx
Normal file
15
web/src/pages/dataset/dataset-title.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
|
type TopTitleProps = {
|
||||||
|
title: ReactNode;
|
||||||
|
description: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function TopTitle({ title, description }: TopTitleProps) {
|
||||||
|
return (
|
||||||
|
<div className="pb-5">
|
||||||
|
<div className="text-2xl font-semibold">{title}</div>
|
||||||
|
<p className="text-text-sub-title pt-2">{description}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -5,6 +5,7 @@ import { DocumentParserType } from '@/constants/knowledge';
|
|||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { useForm, useWatch } from 'react-hook-form';
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
import { TopTitle } from '../dataset-title';
|
||||||
import CategoryPanel from './category-panel';
|
import CategoryPanel from './category-panel';
|
||||||
import { ChunkMethodForm } from './chunk-method-form';
|
import { ChunkMethodForm } from './chunk-method-form';
|
||||||
import { formSchema } from './form-schema';
|
import { formSchema } from './form-schema';
|
||||||
@ -74,13 +75,11 @@ export default function DatasetSettings() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="p-5 ">
|
<section className="p-5 ">
|
||||||
<div className="pb-5">
|
<TopTitle
|
||||||
<div className="text-2xl font-semibold">Configuration</div>
|
title={'Configuration'}
|
||||||
<p className="text-text-sub-title pt-2">
|
description={` Update your knowledge base configuration here, particularly the chunk
|
||||||
Update your knowledge base configuration here, particularly the chunk
|
method.`}
|
||||||
method.
|
></TopTitle>
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-14">
|
<div className="flex gap-14">
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
import { FormContainer } from '@/components/form-container';
|
||||||
|
import { FilterButton } from '@/components/list-filter-bar';
|
||||||
|
import { FilterPopover } from '@/components/list-filter-bar/filter-popover';
|
||||||
|
import { FilterCollection } from '@/components/list-filter-bar/interface';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
import { useTestRetrieval } from '@/hooks/use-knowledge-request';
|
import { useTestRetrieval } from '@/hooks/use-knowledge-request';
|
||||||
import { ITestingChunk } from '@/interfaces/database/knowledge';
|
import { ITestingChunk } from '@/interfaces/database/knowledge';
|
||||||
import { camelCase } from 'lodash';
|
import { camelCase } from 'lodash';
|
||||||
|
import { Plus } from 'lucide-react';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { TopTitle } from '../dataset-title';
|
||||||
import TestingForm from './testing-form';
|
import TestingForm from './testing-form';
|
||||||
|
|
||||||
const similarityList: Array<{ field: keyof ITestingChunk; label: string }> = [
|
const similarityList: Array<{ field: keyof ITestingChunk; label: string }> = [
|
||||||
@ -14,7 +22,7 @@ const similarityList: Array<{ field: keyof ITestingChunk; label: string }> = [
|
|||||||
const ChunkTitle = ({ item }: { item: ITestingChunk }) => {
|
const ChunkTitle = ({ item }: { item: ITestingChunk }) => {
|
||||||
const { t } = useTranslate('knowledgeDetails');
|
const { t } = useTranslate('knowledgeDetails');
|
||||||
return (
|
return (
|
||||||
<div className="flex gap-3 text-xs">
|
<div className="flex gap-3 text-xs text-text-sub-title-invert italic">
|
||||||
{similarityList.map((x) => (
|
{similarityList.map((x) => (
|
||||||
<div key={x.field} className="space-x-1">
|
<div key={x.field} className="space-x-1">
|
||||||
<span>{((item[x.field] as number) * 100).toFixed(2)}</span>
|
<span>{((item[x.field] as number) * 100).toFixed(2)}</span>
|
||||||
@ -26,43 +34,83 @@ const ChunkTitle = ({ item }: { item: ITestingChunk }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function RetrievalTesting() {
|
export default function RetrievalTesting() {
|
||||||
const { loading, setValues, refetch, data } = useTestRetrieval();
|
const {
|
||||||
|
loading,
|
||||||
|
setValues,
|
||||||
|
refetch,
|
||||||
|
data,
|
||||||
|
onPaginationChange,
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
handleFilterSubmit,
|
||||||
|
} = useTestRetrieval();
|
||||||
|
|
||||||
|
const filters: FilterCollection[] = useMemo(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
field: 'doc_ids',
|
||||||
|
label: 'File',
|
||||||
|
list:
|
||||||
|
data.doc_aggs?.map((x) => ({
|
||||||
|
id: x.doc_id,
|
||||||
|
label: x.doc_name,
|
||||||
|
count: x.count,
|
||||||
|
})) ?? [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}, [data.doc_aggs]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="flex divide-x h-full">
|
<div className="p-5">
|
||||||
<div className="p-4">
|
<section className="flex justify-between items-center">
|
||||||
<TestingForm
|
<TopTitle
|
||||||
loading={loading}
|
title={'Configuration'}
|
||||||
setValues={setValues}
|
description={` Update your knowledge base configuration here, particularly the chunk
|
||||||
refetch={refetch}
|
method.`}
|
||||||
></TestingForm>
|
></TopTitle>
|
||||||
</div>
|
<Button>Save as Preset</Button>
|
||||||
<div className="p-4 flex-1 ">
|
</section>
|
||||||
<h2 className="text-4xl font-bold mb-8 px-[10%]">
|
<section className="flex divide-x h-full">
|
||||||
15 Results from 3 files
|
<div className="p-4 flex-1">
|
||||||
</h2>
|
<div className="flex justify-between pb-2.5">
|
||||||
<section className="flex flex-col gap-4 overflow-auto h-[83vh] px-[10%]">
|
<span className="text-text-title font-semibold text-2xl">
|
||||||
{data.chunks.map((x) => (
|
Test setting
|
||||||
<Card
|
</span>
|
||||||
key={x.chunk_id}
|
<Button variant={'outline'}>
|
||||||
className="bg-colors-background-neutral-weak border-colors-outline-neutral-strong"
|
<Plus /> Add New Test
|
||||||
>
|
</Button>
|
||||||
<CardHeader>
|
</div>
|
||||||
<CardTitle>
|
<TestingForm
|
||||||
<div className="flex gap-2 flex-wrap">
|
loading={loading}
|
||||||
<ChunkTitle item={x}></ChunkTitle>
|
setValues={setValues}
|
||||||
</div>
|
refetch={refetch}
|
||||||
</CardTitle>
|
></TestingForm>
|
||||||
</CardHeader>
|
</div>
|
||||||
<CardContent>
|
<div className="p-4 flex-1">
|
||||||
<p className="text-colors-text-neutral-strong">
|
<div className="flex justify-between pb-2.5">
|
||||||
{x.content_with_weight}
|
<span className="text-text-title font-semibold text-2xl">
|
||||||
</p>
|
Test results
|
||||||
</CardContent>
|
</span>
|
||||||
</Card>
|
<FilterPopover filters={filters} onChange={handleFilterSubmit}>
|
||||||
))}
|
<FilterButton></FilterButton>
|
||||||
</section>
|
</FilterPopover>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
<section className="flex flex-col gap-5 overflow-auto h-[76vh] mb-5">
|
||||||
|
{data.chunks?.map((x) => (
|
||||||
|
<FormContainer key={x.chunk_id} className="px-5 py-2.5">
|
||||||
|
<ChunkTitle item={x}></ChunkTitle>
|
||||||
|
<p className="!mt-2.5"> {x.content_with_weight}</p>
|
||||||
|
</FormContainer>
|
||||||
|
))}
|
||||||
|
</section>
|
||||||
|
<RAGFlowPagination
|
||||||
|
total={data.total}
|
||||||
|
onChange={onPaginationChange}
|
||||||
|
current={page}
|
||||||
|
pageSize={pageSize}
|
||||||
|
></RAGFlowPagination>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,12 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
|||||||
import { useForm, useWatch } from 'react-hook-form';
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { RerankFormFields } from '@/components/rerank';
|
import { FormContainer } from '@/components/form-container';
|
||||||
|
import {
|
||||||
|
initialTopKValue,
|
||||||
|
RerankFormFields,
|
||||||
|
topKSchema,
|
||||||
|
} from '@/components/rerank';
|
||||||
import {
|
import {
|
||||||
initialKeywordsSimilarityWeightValue,
|
initialKeywordsSimilarityWeightValue,
|
||||||
initialSimilarityThresholdValue,
|
initialSimilarityThresholdValue,
|
||||||
@ -12,6 +17,7 @@ import {
|
|||||||
SimilaritySliderFormField,
|
SimilaritySliderFormField,
|
||||||
similarityThresholdSchema,
|
similarityThresholdSchema,
|
||||||
} from '@/components/similarity-slider';
|
} from '@/components/similarity-slider';
|
||||||
|
import { ButtonLoading } from '@/components/ui/button';
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -20,7 +26,6 @@ import {
|
|||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { LoadingButton } from '@/components/ui/loading-button';
|
|
||||||
import { Textarea } from '@/components/ui/textarea';
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-item';
|
import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-item';
|
||||||
import { useTestRetrieval } from '@/hooks/use-knowledge-request';
|
import { useTestRetrieval } from '@/hooks/use-knowledge-request';
|
||||||
@ -46,6 +51,7 @@ export default function TestingForm({
|
|||||||
}),
|
}),
|
||||||
...similarityThresholdSchema,
|
...similarityThresholdSchema,
|
||||||
...keywordsSimilarityWeightSchema,
|
...keywordsSimilarityWeightSchema,
|
||||||
|
...topKSchema,
|
||||||
});
|
});
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
const form = useForm<z.infer<typeof formSchema>>({
|
||||||
@ -53,6 +59,7 @@ export default function TestingForm({
|
|||||||
defaultValues: {
|
defaultValues: {
|
||||||
...initialSimilarityThresholdValue,
|
...initialSimilarityThresholdValue,
|
||||||
...initialKeywordsSimilarityWeightValue,
|
...initialKeywordsSimilarityWeightValue,
|
||||||
|
...initialTopKValue,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -71,12 +78,14 @@ export default function TestingForm({
|
|||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||||
<SimilaritySliderFormField
|
<FormContainer className="p-10">
|
||||||
vectorSimilarityWeightName="keywords_similarity_weight"
|
<SimilaritySliderFormField
|
||||||
isTooltipShown
|
vectorSimilarityWeightName="keywords_similarity_weight"
|
||||||
></SimilaritySliderFormField>
|
isTooltipShown
|
||||||
<RerankFormFields></RerankFormFields>
|
></SimilaritySliderFormField>
|
||||||
<UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField>
|
<RerankFormFields></RerankFormFields>
|
||||||
|
<UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField>
|
||||||
|
</FormContainer>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="question"
|
name="question"
|
||||||
@ -94,16 +103,13 @@ export default function TestingForm({
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<LoadingButton
|
<ButtonLoading
|
||||||
variant={'tertiary'}
|
|
||||||
size={'sm'}
|
|
||||||
type="submit"
|
type="submit"
|
||||||
className="w-full"
|
|
||||||
disabled={!!!trim(question)}
|
disabled={!!!trim(question)}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
>
|
>
|
||||||
{t('knowledgeDetails.testingLabel')}
|
{t('knowledgeDetails.testingLabel')}
|
||||||
</LoadingButton>
|
</ButtonLoading>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user