import React, { useEffect, useMemo, useState } from 'react'; import { Box, Textarea, Button, Flex, useTheme, useDisclosure, Table, Thead, Tbody, Tr, Th, Td, TableContainer } from '@chakra-ui/react'; import { useDatasetStore } from '@/web/core/dataset/store/dataset'; import { useSearchTestStore, SearchTestStoreItemType } from '@/web/core/dataset/store/searchTest'; import { postSearchText } from '@/web/core/dataset/api'; import MyIcon from '@fastgpt/web/components/common/Icon'; import { useRequest } from '@/web/common/hooks/useRequest'; import { formatTimeToChatTime } from '@/utils/tools'; import { getErrText } from '@fastgpt/global/common/error/utils'; import { useToast } from '@fastgpt/web/hooks/useToast'; import { customAlphabet } from 'nanoid'; import MyTooltip from '@/components/MyTooltip'; import { QuestionOutlineIcon } from '@chakra-ui/icons'; import { useTranslation } from 'next-i18next'; import { SearchTestResponse } from '@/global/core/dataset/api'; import { DatasetSearchModeEnum, DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constants'; import dynamic from 'next/dynamic'; import { useForm } from 'react-hook-form'; import MySelect from '@/components/Select'; import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; import { fileDownload } from '@/web/common/file/utils'; import { readCsvContent } from '@fastgpt/web/common/file/read/csv'; import { delay } from '@fastgpt/global/common/system/utils'; import QuoteItem from '@/components/core/dataset/QuoteItem'; import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import SearchParamsTip from '@/components/core/dataset/SearchParamsTip'; const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12); const DatasetParamsModal = dynamic(() => import('@/components/core/module/DatasetParamsModal')); type FormType = { inputText: string; searchParams: { searchMode: `${DatasetSearchModeEnum}`; similarity?: number; limit?: number; usingReRank?: boolean; searchEmptyText?: string; datasetSearchUsingExtensionQuery?: boolean; datasetSearchExtensionModel?: string; datasetSearchExtensionBg?: string; }; }; const Test = ({ datasetId }: { datasetId: string }) => { const { t } = useTranslation(); const theme = useTheme(); const { toast } = useToast(); const { llmModelList } = useSystemStore(); const { datasetDetail } = useDatasetStore(); const { pushDatasetTestItem } = useSearchTestStore(); const [inputType, setInputType] = useState<'text' | 'file'>('text'); const [datasetTestItem, setDatasetTestItem] = useState(); const [refresh, setRefresh] = useState(false); const [isFocus, setIsFocus] = useState(false); const { File, onOpen } = useSelectFile({ fileType: '.csv', multiple: false }); const [selectFile, setSelectFile] = useState(); const { getValues, setValue, register, handleSubmit } = useForm({ defaultValues: { inputText: '', searchParams: { searchMode: DatasetSearchModeEnum.embedding, usingReRank: false, limit: 5000, similarity: 0, datasetSearchUsingExtensionQuery: false, datasetSearchExtensionModel: llmModelList[0].model, datasetSearchExtensionBg: '' } } }); const searchModeData = DatasetSearchModeMap[getValues(`searchParams.searchMode`)]; const { isOpen: isOpenSelectMode, onOpen: onOpenSelectMode, onClose: onCloseSelectMode } = useDisclosure(); const { mutate: onTextTest, isLoading: textTestIsLoading } = useRequest({ mutationFn: ({ inputText, searchParams }: FormType) => postSearchText({ datasetId, text: inputText.trim(), ...searchParams }), onSuccess(res: SearchTestResponse) { if (!res || res.list.length === 0) { return toast({ status: 'warning', title: t('dataset.test.noResult') }); } const testItem: SearchTestStoreItemType = { id: nanoid(), datasetId, text: getValues('inputText').trim(), time: new Date(), results: res.list, duration: res.duration, searchMode: res.searchMode, usingReRank: res.usingReRank, limit: res.limit, similarity: res.similarity, usingQueryExtension: res.usingQueryExtension }; pushDatasetTestItem(testItem); setDatasetTestItem(testItem); }, onError(err) { toast({ title: getErrText(err), status: 'error' }); } }); // const { mutate: onFileTest, isLoading: fileTestIsLoading } = useRequest({ // mutationFn: async ({ searchParams }: FormType) => { // if (!selectFile) return Promise.reject('File is not selected'); // const { data } = await readCsvContent({ file: selectFile }); // const testList = data.slice(0, 100); // const results: SearchTestResponse[] = []; // for await (const item of testList) { // try { // const result = await postSearchText({ datasetId, text: item[0].trim(), ...searchParams }); // results.push(result); // } catch (error) { // await delay(500); // } // } // return results; // }, // onSuccess(res: SearchTestResponse[]) { // console.log(res); // }, // onError(err) { // toast({ // title: getErrText(err), // status: 'error' // }); // } // }); const onSelectFile = async (files: File[]) => { const file = files[0]; if (!file) return; setSelectFile(file); }; useEffect(() => { setDatasetTestItem(undefined); }, [datasetId]); return ( {/* left */} {/* header */} {t('core.dataset.test.Test Text')} ), value: 'text' } // { // label: ( // // // // {t('core.dataset.test.Batch test')} // // // ), // value: 'file' // } ]} value={inputType} onchange={(e) => setInputType(e)} /> {inputType === 'text' && (