mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-29 09:44:47 +00:00
v4.6.2 (#523)
This commit is contained in:
@@ -90,13 +90,15 @@ function App({ Component, pageProps }: AppProps) {
|
||||
hiId && localStorage.setItem('inviterId', hiId);
|
||||
}, [hiId]);
|
||||
|
||||
const title = feConfigs?.systemTitle || process.env.SYSTEM_NAME || '';
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{feConfigs?.systemTitle || process.env.SYSTEM_NAME || ''}</title>
|
||||
<title>{title}</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="FastGPT 是一个大模型应用编排系统,提供开箱即用的数据处理、模型调用等能力,可以快速的构建知识库并通过 Flow 可视化进行工作流编排,实现复杂的知识库场景!"
|
||||
content={`${title} 是一个大模型应用编排系统,提供开箱即用的数据处理、模型调用等能力,可以快速的构建知识库并通过 Flow 可视化进行工作流编排,实现复杂的知识库场景!`}
|
||||
/>
|
||||
<meta
|
||||
name="viewport"
|
||||
|
@@ -3,7 +3,6 @@ import { Html, Head, Main, NextScript } from 'next/document';
|
||||
export default function Document() {
|
||||
return (
|
||||
<Html>
|
||||
<title>{process.env.SYSTEM_NAME || 'FastGPT'}</title>
|
||||
<Head />
|
||||
<body>
|
||||
<Main />
|
||||
|
@@ -152,6 +152,7 @@ async function init(limit: number): Promise<any> {
|
||||
collectionId: data.collection_id,
|
||||
q: data.q,
|
||||
a: data.a,
|
||||
fullTextToken: '',
|
||||
indexes: [
|
||||
{
|
||||
defaultIndex: !data.a,
|
||||
|
80
projects/app/src/pages/api/admin/initv462-2.ts
Normal file
80
projects/app/src/pages/api/admin/initv462-2.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { delay } from '@/utils/tools';
|
||||
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||
import { MongoApp } from '@fastgpt/service/core/app/schema';
|
||||
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||
import { DatasetSearchModeEnum } from '@fastgpt/global/core/dataset/constant';
|
||||
import { ModuleDataTypeEnum, ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||
import { ModuleItemType } from '@fastgpt/global/core/module/type';
|
||||
|
||||
let success = 0;
|
||||
/* pg 中的数据搬到 mongo dataset.datas 中,并做映射 */
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
const { limit = 50 } = req.body as { limit: number };
|
||||
await authCert({ req, authRoot: true });
|
||||
await connectToDatabase();
|
||||
success = 0;
|
||||
|
||||
console.log('total', await MongoApp.countDocuments());
|
||||
|
||||
await initApp(limit);
|
||||
|
||||
jsonRes(res, {
|
||||
message: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
jsonRes(res, {
|
||||
code: 500,
|
||||
error
|
||||
});
|
||||
}
|
||||
}
|
||||
export async function initApp(limit = 50): Promise<any> {
|
||||
try {
|
||||
const apps = await MongoApp.find({ inited: false }).limit(limit);
|
||||
if (apps.length === 0) return;
|
||||
|
||||
const result = await Promise.allSettled(
|
||||
apps.map(async (app) => {
|
||||
// 遍历app的modules,找到 datasetSearch, 如果 rerank=true, searchMode = embFullTextReRank, 否则等于embedding
|
||||
const modules = JSON.parse(JSON.stringify(app.modules)) as ModuleItemType[];
|
||||
modules.forEach((module) => {
|
||||
if (module.flowType === FlowNodeTypeEnum.datasetSearchNode) {
|
||||
module.inputs.forEach((input, i) => {
|
||||
if (input.key === 'rerank') {
|
||||
const val = !!input.value as boolean;
|
||||
module.inputs.splice(i, 1, {
|
||||
key: ModuleInputKeyEnum.datasetSearchMode,
|
||||
type: FlowNodeInputTypeEnum.hidden,
|
||||
label: 'core.dataset.search.Mode',
|
||||
valueType: ModuleDataTypeEnum.string,
|
||||
showTargetInApp: false,
|
||||
showTargetInPlugin: false,
|
||||
value: val
|
||||
? DatasetSearchModeEnum.embFullTextReRank
|
||||
: DatasetSearchModeEnum.embedding
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
app.modules = modules;
|
||||
app.inited = true;
|
||||
await app.save();
|
||||
})
|
||||
);
|
||||
|
||||
success += result.filter((item) => item.status === 'fulfilled').length;
|
||||
console.log(`success: ${success}`);
|
||||
return initApp(limit);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
await delay(1000);
|
||||
return initApp(limit);
|
||||
}
|
||||
}
|
@@ -8,6 +8,7 @@ import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type.d';
|
||||
import type { ModuleItemType } from '@fastgpt/global/core/module/type';
|
||||
import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||
import { FormatForm2ModulesProps } from '@fastgpt/global/core/app/api';
|
||||
import { DatasetSearchModeEnum } from '@fastgpt/global/core/dataset/constant';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
try {
|
||||
@@ -378,7 +379,7 @@ function datasetTemplate({
|
||||
},
|
||||
{
|
||||
key: 'similarity',
|
||||
value: 0.5,
|
||||
value: 0.4,
|
||||
type: FlowNodeInputTypeEnum.slider,
|
||||
label: '相似度',
|
||||
connected: true
|
||||
@@ -403,13 +404,23 @@ function datasetTemplate({
|
||||
connected: true
|
||||
},
|
||||
{
|
||||
key: 'rerank',
|
||||
type: FlowNodeInputTypeEnum.switch,
|
||||
label: '结果重排',
|
||||
description: '将召回的结果进行进一步重排,可增加召回率',
|
||||
plusField: true,
|
||||
connected: true,
|
||||
value: true
|
||||
key: 'searchMode',
|
||||
type: 'hidden',
|
||||
label: 'core.dataset.search.Mode',
|
||||
valueType: 'string',
|
||||
showTargetInApp: false,
|
||||
showTargetInPlugin: false,
|
||||
value: DatasetSearchModeEnum.embFullTextReRank,
|
||||
connected: false
|
||||
},
|
||||
{
|
||||
key: 'datasetParamsModal',
|
||||
type: 'selectDatasetParamsModal',
|
||||
label: '',
|
||||
connected: false,
|
||||
valueType: 'any',
|
||||
showTargetInApp: false,
|
||||
showTargetInPlugin: false
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
|
@@ -312,13 +312,23 @@ function datasetTemplate(formData: AppSimpleEditFormType): ModuleItemType[] {
|
||||
connected: true
|
||||
},
|
||||
{
|
||||
key: 'rerank',
|
||||
type: FlowNodeInputTypeEnum.switch,
|
||||
label: '结果重排',
|
||||
description: '将召回的结果进行进一步重排,可增加召回率',
|
||||
plusField: true,
|
||||
key: 'searchMode',
|
||||
type: 'hidden',
|
||||
label: 'core.dataset.search.Mode',
|
||||
valueType: 'string',
|
||||
showTargetInApp: false,
|
||||
showTargetInPlugin: false,
|
||||
value: formData.dataset.searchMode,
|
||||
connected: false
|
||||
},
|
||||
{
|
||||
key: 'datasetParamsModal',
|
||||
type: 'selectDatasetParamsModal',
|
||||
label: '',
|
||||
connected: false,
|
||||
value: formData.dataset.rerank
|
||||
valueType: 'any',
|
||||
showTargetInApp: false,
|
||||
showTargetInPlugin: false
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
|
@@ -4,7 +4,6 @@ import { connectToDatabase } from '@/service/mongo';
|
||||
import { MongoApp } from '@fastgpt/service/core/app/schema';
|
||||
import type { AppUpdateParams } from '@fastgpt/global/core/app/api';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { ModuleOutputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||
|
||||
/* 获取我的模型 */
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
|
@@ -67,8 +67,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
'limit.exportKbTime': new Date()
|
||||
});
|
||||
});
|
||||
|
||||
cursor.on('error', (err) => {
|
||||
addLog.error(`export dataset error`, err);
|
||||
res.status(500);
|
||||
res.end();
|
||||
});
|
||||
} catch (err) {
|
||||
res.status(500);
|
||||
addLog.error(`export dataset error`, err);
|
||||
jsonRes(res, {
|
||||
code: 500,
|
||||
error: err
|
||||
|
@@ -15,7 +15,7 @@ import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
try {
|
||||
await connectToDatabase();
|
||||
const { datasetId, text, limit = 20, rerank } = req.body as SearchTestProps;
|
||||
const { datasetId, text, limit = 20, searchMode } = req.body as SearchTestProps;
|
||||
|
||||
if (!datasetId || !text) {
|
||||
throw new Error('缺少参数');
|
||||
@@ -40,7 +40,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
|
||||
model: dataset.vectorModel,
|
||||
limit: Math.min(limit, 50),
|
||||
datasetIds: [datasetId],
|
||||
rerank
|
||||
searchMode
|
||||
});
|
||||
|
||||
// push bill
|
||||
|
@@ -14,7 +14,8 @@ import {
|
||||
defaultQGModels,
|
||||
defaultVectorModels,
|
||||
defaultAudioSpeechModels,
|
||||
defaultWhisperModel
|
||||
defaultWhisperModel,
|
||||
defaultReRankModels
|
||||
} from '@fastgpt/global/core/ai/model';
|
||||
import { SimpleModeTemplate_FastGPT_Universal } from '@/global/core/app/constants';
|
||||
import { getSimpleTemplatesFromPlus } from '@/service/core/app/utils';
|
||||
@@ -31,11 +32,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
cqModels: global.cqModels,
|
||||
extractModels: global.extractModels,
|
||||
vectorModels: global.vectorModels,
|
||||
audioSpeechModels: global.audioSpeechModels.map((item) => ({
|
||||
reRankModels: global.reRankModels.map((item) => ({
|
||||
...item,
|
||||
baseUrl: undefined,
|
||||
key: undefined
|
||||
requestUrl: undefined,
|
||||
requestAuth: undefined
|
||||
})),
|
||||
audioSpeechModels: global.audioSpeechModels,
|
||||
priceMd: global.priceMd,
|
||||
systemVersion: global.systemVersion || '0.0.0',
|
||||
simpleModeTemplates: global.simpleModeTemplates
|
||||
@@ -50,12 +52,11 @@ const defaultSystemEnv: SystemEnvType = {
|
||||
};
|
||||
const defaultFeConfigs: FeConfigsType = {
|
||||
show_emptyChat: true,
|
||||
show_contact: true,
|
||||
show_git: true,
|
||||
docUrl: 'https://docs.fastgpt.in',
|
||||
show_register: false,
|
||||
docUrl: 'https://doc.fastgpt.in',
|
||||
openAPIDocUrl: 'https://doc.fastgpt.in/docs/development/openapi',
|
||||
systemTitle: 'FastGPT',
|
||||
authorText: 'Made by FastGPT Team.',
|
||||
limit: {
|
||||
exportLimitMinutes: 0
|
||||
},
|
||||
@@ -99,7 +100,14 @@ export function setDefaultData(res?: ConfigFileType) {
|
||||
? { ...defaultSystemEnv, ...res.SystemParams }
|
||||
: defaultSystemEnv;
|
||||
global.feConfigs = res?.FeConfig
|
||||
? { ...defaultFeConfigs, ...res.FeConfig, isPlus: !!res.SystemParams?.pluginBaseUrl }
|
||||
? {
|
||||
concatMd: res?.FeConfig?.show_git
|
||||
? '* 项目开源地址: [FastGPT GitHub](https://github.com/labring/FastGPT)\n* 交流群: '
|
||||
: '',
|
||||
...defaultFeConfigs,
|
||||
...res.FeConfig,
|
||||
isPlus: !!res.SystemParams?.pluginBaseUrl
|
||||
}
|
||||
: defaultFeConfigs;
|
||||
|
||||
global.chatModels = res?.ChatModels || defaultChatModels;
|
||||
@@ -110,6 +118,8 @@ export function setDefaultData(res?: ConfigFileType) {
|
||||
|
||||
global.vectorModels = res?.VectorModels || defaultVectorModels;
|
||||
|
||||
global.reRankModels = res?.ReRankModels || defaultReRankModels;
|
||||
|
||||
global.audioSpeechModels = res?.AudioSpeechModels || defaultAudioSpeechModels;
|
||||
|
||||
global.whisperModel = res?.WhisperModel || defaultWhisperModel;
|
||||
|
@@ -15,7 +15,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
|
||||
try {
|
||||
let { input, model, billId } = req.body as Props;
|
||||
await connectToDatabase();
|
||||
const { teamId, tmbId } = await authCert({ req, authToken: true });
|
||||
const { teamId, tmbId } = await authCert({ req, authToken: true, authApiKey: true });
|
||||
|
||||
if (!Array.isArray(input) || typeof input !== 'string') {
|
||||
throw new Error('input is nor array or string');
|
||||
|
42
projects/app/src/pages/api/v1/rerank.ts
Normal file
42
projects/app/src/pages/api/v1/rerank.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||
import { withNextCors } from '@fastgpt/service/common/middle/cors';
|
||||
import { pushReRankBill } from '@/service/support/wallet/bill/push';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { authTeamBalance } from '@/service/support/permission/auth/bill';
|
||||
import { PostReRankProps } from '@fastgpt/global/core/ai/api';
|
||||
import { reRankRecall } from '@/service/core/ai/rerank';
|
||||
|
||||
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
try {
|
||||
let { query, inputs } = req.body as PostReRankProps;
|
||||
await connectToDatabase();
|
||||
const { teamId, tmbId } = await authCert({
|
||||
req,
|
||||
authApiKey: true
|
||||
});
|
||||
await authTeamBalance(teamId);
|
||||
|
||||
// max 150 length
|
||||
inputs = inputs.slice(0, 150);
|
||||
|
||||
const result = await reRankRecall({ query, inputs });
|
||||
|
||||
pushReRankBill({
|
||||
teamId,
|
||||
tmbId,
|
||||
source: 'api'
|
||||
});
|
||||
|
||||
jsonRes(res, {
|
||||
data: result
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
jsonRes(res, {
|
||||
code: 500,
|
||||
error: err
|
||||
});
|
||||
}
|
||||
});
|
@@ -33,7 +33,6 @@ import { AppSchema } from '@fastgpt/global/core/app/type.d';
|
||||
import { delModelById } from '@/web/core/app/api';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { getGuideModule } from '@fastgpt/global/core/module/utils';
|
||||
import { DatasetParamsModal } from '@/components/core/module/DatasetSelectModal';
|
||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
@@ -56,6 +55,7 @@ import VariableEdit from '@/components/core/module/Flow/components/modules/Varia
|
||||
|
||||
const InfoModal = dynamic(() => import('../InfoModal'));
|
||||
const DatasetSelectModal = dynamic(() => import('@/components/core/module/DatasetSelectModal'));
|
||||
const DatasetParamsModal = dynamic(() => import('@/components/core/module/DatasetParamsModal'));
|
||||
const AIChatSettingsModal = dynamic(() => import('@/components/core/module/AIChatSettingsModal'));
|
||||
|
||||
function ConfigForm({
|
||||
@@ -72,7 +72,6 @@ function ConfigForm({
|
||||
const { appDetail, updateAppDetail } = useAppStore();
|
||||
const { loadAllDatasets, allDatasets } = useDatasetStore();
|
||||
const { isPc } = useSystemStore();
|
||||
const [editVariable, setEditVariable] = useState<VariableItemType>();
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
|
||||
const { register, setValue, getValues, reset, handleSubmit, control } =
|
||||
@@ -197,8 +196,8 @@ function ConfigForm({
|
||||
})}
|
||||
>
|
||||
<Box fontSize={['md', 'xl']} fontWeight={'bold'}>
|
||||
应用配置
|
||||
<MyTooltip label={'仅包含基础功能,复杂 agent 功能请使用高级编排。'} forceShow>
|
||||
{t('core.app.App params config')}
|
||||
<MyTooltip label={t('core.app.Simple Config Tip')} forceShow>
|
||||
<QuestionOutlineIcon ml={2} fontSize={'md'} />
|
||||
</MyTooltip>
|
||||
</Box>
|
||||
@@ -215,7 +214,7 @@ function ConfigForm({
|
||||
}
|
||||
}}
|
||||
>
|
||||
{isPc ? '保存并预览' : '保存'}
|
||||
{isPc ? t('core.app.Save and preview') : t('common.Save')}
|
||||
</Button>
|
||||
</Flex>
|
||||
|
||||
@@ -248,7 +247,7 @@ function ConfigForm({
|
||||
<Box {...BoxStyles} mt={2}>
|
||||
<Flex alignItems={'center'}>
|
||||
<Image alt={''} src={'/imgs/module/userGuide.png'} w={'18px'} />
|
||||
<Box mx={2}>对话开场白</Box>
|
||||
<Box mx={2}>{t('core.app.Welcome Text')}</Box>
|
||||
<MyTooltip label={welcomeTextTip} forceShow>
|
||||
<QuestionOutlineIcon />
|
||||
</MyTooltip>
|
||||
@@ -351,7 +350,7 @@ function ConfigForm({
|
||||
</Flex>
|
||||
)}
|
||||
{(selectSimpleTemplate.systemForm.dataset.limit ||
|
||||
selectSimpleTemplate.systemForm.dataset.rerank ||
|
||||
selectSimpleTemplate.systemForm.dataset.searchMode ||
|
||||
selectSimpleTemplate.systemForm.dataset.searchEmptyText ||
|
||||
selectSimpleTemplate.systemForm.dataset.similarity) && (
|
||||
<Flex alignItems={'center'} ml={3} {...BoxBtnStyles} onClick={onOpenKbParams}>
|
||||
@@ -459,7 +458,7 @@ function ConfigForm({
|
||||
<DatasetParamsModal
|
||||
{...getValues('dataset')}
|
||||
onClose={onCloseKbParams}
|
||||
onChange={(e) => {
|
||||
onSuccess={(e) => {
|
||||
setValue('dataset', {
|
||||
...getValues('dataset'),
|
||||
...e
|
||||
|
@@ -66,12 +66,12 @@ const MyApps = () => {
|
||||
);
|
||||
|
||||
/* 加载模型 */
|
||||
useQuery(['loadApps'], () => loadMyApps(true), {
|
||||
const { isFetching } = useQuery(['loadApps'], () => loadMyApps(true), {
|
||||
refetchOnMount: true
|
||||
});
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
<PageContainer isLoading={isFetching}>
|
||||
<Flex pt={3} px={5} alignItems={'center'}>
|
||||
<Flex flex={1} alignItems={'center'}>
|
||||
<Image src={'/imgs/module/ai.svg'} alt={''} mr={2} h={'24px'} />
|
||||
|
@@ -20,7 +20,7 @@ const Navbar = () => {
|
||||
const { isOpen: isOpenMenu, onOpen: onOpenMenu, onClose: onCloseMenu } = useDisclosure();
|
||||
const { isPc } = useSystemStore();
|
||||
const menuList = [
|
||||
...(feConfigs?.show_contact
|
||||
...(feConfigs?.concatMd
|
||||
? [
|
||||
{
|
||||
label: t('home.Commercial'),
|
||||
|
@@ -5,7 +5,10 @@ import { useImportStore, SelectorContainer, PreviewFileOrChunk } from './Provide
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
const fileExtension = '.csv';
|
||||
const csvTemplate = `index,content\n"被索引的内容","对应的答案。CSV 中请注意内容不能包含双引号,双引号是列分割符号"\n"什么是 laf","laf 是一个云函数开发平台……",""\n"什么是 sealos","Sealos 是以 kubernetes 为内核的云操作系统发行版,可以……"`;
|
||||
const csvTemplate = `index,content
|
||||
"必填内容","可选内容。CSV 中请注意内容不能包含双引号,双引号是列分割符号"
|
||||
"结合人工智能的演进历程,AIGC的发展大致可以分为三个阶段,即:早期萌芽阶段(20世纪50年代至90年代中期)、沉淀积累阶段(20世纪90年代中期至21世纪10年代中期),以及快速发展展阶段(21世纪10年代中期至今)。",""
|
||||
"AIGC发展分为几个阶段?","早期萌芽阶段(20世纪50年代至90年代中期)、沉淀积累阶段(20世纪90年代中期至21世纪10年代中期)、快速发展展阶段(21世纪10年代中期至今)"`;
|
||||
|
||||
const CsvImport = () => {
|
||||
const { t } = useTranslation();
|
||||
|
@@ -1,5 +1,15 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { Box, Textarea, Button, Flex, useTheme, Grid, Progress, Switch } from '@chakra-ui/react';
|
||||
import {
|
||||
Box,
|
||||
Textarea,
|
||||
Button,
|
||||
Flex,
|
||||
useTheme,
|
||||
Grid,
|
||||
Progress,
|
||||
Switch,
|
||||
useDisclosure
|
||||
} from '@chakra-ui/react';
|
||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
||||
import { useSearchTestStore, SearchTestStoreItemType } from '@/web/core/dataset/store/searchTest';
|
||||
import { getDatasetDataItemById, postSearchText } from '@/web/core/dataset/api';
|
||||
@@ -13,12 +23,14 @@ import { useToast } from '@/web/common/hooks/useToast';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
import MyTooltip from '@/components/MyTooltip';
|
||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
import { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { feConfigs } from '@/web/common/system/staticData';
|
||||
import { SearchTestResponse } from '../../../../global/core/dataset/api';
|
||||
import { SearchTestResponse } from '@/global/core/dataset/api';
|
||||
import { DatasetSearchModeEnum, DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constant';
|
||||
import dynamic from 'next/dynamic';
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12);
|
||||
|
||||
const DatasetParamsModal = dynamic(() => import('@/components/core/module/DatasetParamsModal'));
|
||||
|
||||
const Test = ({ datasetId }: { datasetId: string }) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
@@ -30,15 +42,24 @@ const Test = ({ datasetId }: { datasetId: string }) => {
|
||||
const [inputText, setInputText] = useState('');
|
||||
const [datasetTestItem, setDatasetTestItem] = useState<SearchTestStoreItemType>();
|
||||
const [editInputData, setEditInputData] = useState<InputDataType & { collectionId: string }>();
|
||||
const [rerank, setRerank] = useState(false);
|
||||
const [searchMode, setSearchMode] = useState<`${DatasetSearchModeEnum}`>(
|
||||
DatasetSearchModeEnum.embedding
|
||||
);
|
||||
const searchModeData = DatasetSearchModeMap[searchMode];
|
||||
|
||||
const kbTestHistory = useMemo(
|
||||
const {
|
||||
isOpen: isOpenSelectMode,
|
||||
onOpen: onOpenSelectMode,
|
||||
onClose: onCloseSelectMode
|
||||
} = useDisclosure();
|
||||
|
||||
const testHistories = useMemo(
|
||||
() => datasetTestList.filter((item) => item.datasetId === datasetId),
|
||||
[datasetId, datasetTestList]
|
||||
);
|
||||
|
||||
const { mutate, isLoading } = useRequest({
|
||||
mutationFn: () => postSearchText({ datasetId, text: inputText.trim(), rerank, limit: 30 }),
|
||||
mutationFn: () => postSearchText({ datasetId, text: inputText.trim(), searchMode, limit: 30 }),
|
||||
onSuccess(res: SearchTestResponse) {
|
||||
if (!res || res.list.length === 0) {
|
||||
return toast({
|
||||
@@ -71,6 +92,7 @@ const Test = ({ datasetId }: { datasetId: string }) => {
|
||||
|
||||
return (
|
||||
<Box h={'100%'} display={['block', 'flex']}>
|
||||
{/* input */}
|
||||
<Box
|
||||
h={['auto', '100%']}
|
||||
display={['block', 'flex']}
|
||||
@@ -86,12 +108,14 @@ const Test = ({ datasetId }: { datasetId: string }) => {
|
||||
<MyIcon mr={2} name={'text'} w={'18px'} h={'18px'} color={'myBlue.700'} />
|
||||
{t('core.dataset.test.Test Text')}
|
||||
</Box>
|
||||
{feConfigs?.isPlus && (
|
||||
<Flex alignItems={'center'}>
|
||||
{t('dataset.recall.rerank')}
|
||||
<Switch ml={1} isChecked={rerank} onChange={(e) => setRerank(e.target.checked)} />
|
||||
</Flex>
|
||||
)}
|
||||
<Button
|
||||
variant={'base'}
|
||||
leftIcon={<MyIcon name={searchModeData.icon as any} w={'14px'} />}
|
||||
size={'sm'}
|
||||
onClick={onOpenSelectMode}
|
||||
>
|
||||
{t(searchModeData.title)}
|
||||
</Button>
|
||||
</Flex>
|
||||
<Textarea
|
||||
rows={6}
|
||||
@@ -122,7 +146,7 @@ const Test = ({ datasetId }: { datasetId: string }) => {
|
||||
<Box w={'80px'}>{t('common.Time')}</Box>
|
||||
<Box w={'14px'}></Box>
|
||||
</Flex>
|
||||
{kbTestHistory.map((item) => (
|
||||
{testHistories.map((item) => (
|
||||
<Flex
|
||||
key={item.id}
|
||||
p={1}
|
||||
@@ -162,6 +186,7 @@ const Test = ({ datasetId }: { datasetId: string }) => {
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
{/* result show */}
|
||||
<Box p={4} h={['auto', '100%']} overflow={'overlay'} flex={1}>
|
||||
{!datasetTestItem?.results || datasetTestItem.results.length === 0 ? (
|
||||
<Flex
|
||||
@@ -307,6 +332,15 @@ const Test = ({ datasetId }: { datasetId: string }) => {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{isOpenSelectMode && (
|
||||
<DatasetParamsModal
|
||||
searchMode={searchMode}
|
||||
onClose={onCloseSelectMode}
|
||||
onSuccess={(e) => {
|
||||
setSearchMode(e.searchMode);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@@ -11,7 +11,6 @@ import { feConfigs } from '@/web/common/system/staticData';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyIcon from '@/components/Icon';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 8);
|
||||
|
||||
interface Props {
|
||||
@@ -86,6 +85,8 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
: [])
|
||||
];
|
||||
|
||||
const isCommunityVersion = feConfigs?.show_register === false && feConfigs?.show_git;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box fontWeight={'bold'} fontSize={'2xl'} textAlign={'center'}>
|
||||
@@ -94,7 +95,7 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
<form onSubmit={handleSubmit(onclickLogin)}>
|
||||
<FormControl mt={8} isInvalid={!!errors.username}>
|
||||
<Input
|
||||
placeholder="邮箱/手机号/用户名"
|
||||
placeholder={isCommunityVersion ? '使用root用户登录' : '邮箱/手机号/用户名'}
|
||||
size={['md', 'lg']}
|
||||
{...register('username', {
|
||||
required: '邮箱/手机号/用户名不能为空'
|
||||
@@ -108,7 +109,7 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
<Input
|
||||
type={'password'}
|
||||
size={['md', 'lg']}
|
||||
placeholder="密码"
|
||||
placeholder={isCommunityVersion ? 'root密码为你设置的环境变量' : '密码'}
|
||||
{...register('password', {
|
||||
required: '密码不能为空',
|
||||
maxLength: {
|
||||
|
@@ -13,7 +13,6 @@ import { clearToken, setToken } from '@/web/support/user/auth';
|
||||
import { feConfigs } from '@/web/common/system/staticData';
|
||||
import CommunityModal from '@/components/CommunityModal';
|
||||
import Script from 'next/script';
|
||||
import { loginOut } from '@/web/support/user/api';
|
||||
const RegisterForm = dynamic(() => import('./components/RegisterForm'));
|
||||
const ForgetPasswordForm = dynamic(() => import('./components/ForgetPasswordForm'));
|
||||
|
||||
@@ -114,10 +113,10 @@ const Login = () => {
|
||||
>
|
||||
<DynamicComponent type={pageType} />
|
||||
|
||||
{feConfigs?.show_contact && (
|
||||
{feConfigs?.concatMd && (
|
||||
<Box
|
||||
fontSize={'sm'}
|
||||
color={'myGray.600'}
|
||||
fontWeight={'bold'}
|
||||
color={'myBlue.700'}
|
||||
cursor={'pointer'}
|
||||
position={'absolute'}
|
||||
right={5}
|
||||
|
Reference in New Issue
Block a user