mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-30 18:48:55 +00:00
V4.6.6-2 (#673)
This commit is contained in:
@@ -151,7 +151,7 @@ export const QuoteList = React.memo(function QuoteList({
|
||||
{item.q.length + (item.a?.length || 0)}
|
||||
</Flex>
|
||||
</MyTooltip>
|
||||
{!isShare && item.score && (
|
||||
{/* {!isShare && item.score && (
|
||||
<MyTooltip label={t('core.dataset.Similarity')}>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'kbTest'} w={'12px'} />
|
||||
@@ -167,7 +167,7 @@ export const QuoteList = React.memo(function QuoteList({
|
||||
<Box>{item.score.toFixed(4)}</Box>
|
||||
</Flex>
|
||||
</MyTooltip>
|
||||
)}
|
||||
)} */}
|
||||
<Box flex={1} />
|
||||
{item.id && (
|
||||
<MyTooltip label={t('core.dataset.data.Edit')}>
|
||||
|
@@ -205,9 +205,9 @@ const ResponseTags = ({
|
||||
</Tag>
|
||||
</MyTooltip>
|
||||
)}
|
||||
<MyTooltip label={'点击查看完整响应'}>
|
||||
<MyTooltip label={t('core.chat.response.Read complete response tips')}>
|
||||
<Tag colorSchema="gray" cursor={'pointer'} {...TagStyles} onClick={onOpenWholeModal}>
|
||||
{t('chat.Complete Response')}
|
||||
{t('core.chat.response.Read complete response')}
|
||||
</Tag>
|
||||
</MyTooltip>
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import Tabs from '../Tabs';
|
||||
import MyModal from '../MyModal';
|
||||
import MyTooltip from '../MyTooltip';
|
||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
import { formatPrice } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import Markdown from '../Markdown';
|
||||
import { QuoteList } from './QuoteModal';
|
||||
import { DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constant';
|
||||
@@ -19,7 +19,7 @@ function Row({
|
||||
rawDom
|
||||
}: {
|
||||
label: string;
|
||||
value?: string | number;
|
||||
value?: string | number | boolean;
|
||||
rawDom?: React.ReactNode;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
@@ -70,7 +70,7 @@ const WholeResponseModal = ({
|
||||
iconSrc="/imgs/modal/wholeRecord.svg"
|
||||
title={
|
||||
<Flex alignItems={'center'}>
|
||||
{t('chat.Complete Response')}
|
||||
{t('core.chat.response.Complete Response')}
|
||||
<MyTooltip label={'从左往右,为各个模块的响应顺序'}>
|
||||
<QuestionOutlineIcon ml={2} />
|
||||
</MyTooltip>
|
||||
@@ -133,15 +133,16 @@ const ResponseBox = React.memo(function ResponseBox({
|
||||
{activeModule?.price !== undefined && (
|
||||
<Row
|
||||
label={t('core.chat.response.module price')}
|
||||
value={`¥${formatPrice(activeModule?.price)}`}
|
||||
value={`¥${formatStorePrice2Read(activeModule?.price)}`}
|
||||
/>
|
||||
)}
|
||||
<Row
|
||||
label={t('core.chat.response.module time')}
|
||||
value={`${activeModule?.runningTime || 0}s`}
|
||||
/>
|
||||
<Row label={t('core.chat.response.module tokens')} value={`${activeModule?.tokens}`} />
|
||||
<Row label={t('core.chat.response.module model')} value={activeModule?.model} />
|
||||
<Row label={t('wallet.bill.Input Token Length')} value={`${activeModule?.inputTokens}`} />
|
||||
<Row label={t('wallet.bill.Output Token Length')} value={`${activeModule?.outputTokens}`} />
|
||||
<Row label={t('core.chat.response.module query')} value={activeModule?.query} />
|
||||
<Row
|
||||
label={t('core.chat.response.context total length')}
|
||||
@@ -193,6 +194,10 @@ const ResponseBox = React.memo(function ResponseBox({
|
||||
)}
|
||||
<Row label={t('core.chat.response.module similarity')} value={activeModule?.similarity} />
|
||||
<Row label={t('core.chat.response.module limit')} value={activeModule?.limit} />
|
||||
<Row
|
||||
label={t('core.chat.response.search using reRank')}
|
||||
value={activeModule?.searchUsingReRank}
|
||||
/>
|
||||
|
||||
{/* classify question */}
|
||||
<Row
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 821 B After Width: | Height: | Size: 821 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1703840539554" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7163" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M224.63064 14.207408h566.760385a4.266489 4.266489 0 0 1 4.735803 4.735803v227.915837a4.266489 4.266489 0 0 1-4.735803 4.735802H224.63064a4.266489 4.266489 0 0 1-4.735802-4.735802V18.943211a4.266489 4.266489 0 0 1 4.735802-4.735803z" fill="#4A8BFD" p-id="7164"></path><path d="M781.876755 28.414816v209.057956H234.059581v-209.057956h547.817174M791.34836 0H224.417316a18.943211 18.943211 0 0 0-18.943211 18.943211v227.915837a18.943211 18.943211 0 0 0 18.943211 18.94321h566.760385a18.943211 18.943211 0 0 0 18.943211-18.94321V18.943211a18.943211 18.943211 0 0 0-18.772552-18.943211z" fill="#333333" p-id="7165"></path><path d="M224.63064 393.028957h566.760385a4.266489 4.266489 0 0 1 4.735803 4.735803v227.915837a4.266489 4.266489 0 0 1-4.735803 4.735802H224.63064a4.266489 4.266489 0 0 1-4.735802-4.735802V397.76476a4.266489 4.266489 0 0 1 4.735802-4.735803z" fill="#EDEDED" p-id="7166"></path><path d="M781.876755 407.535019v208.503313H234.059581V407.535019h547.817174m9.471605-28.414816H224.417316a18.943211 18.943211 0 0 0-18.943211 18.943211v227.446523a18.943211 18.943211 0 0 0 18.943211 18.943211h566.760385a18.943211 18.943211 0 0 0 18.943211-18.943211V398.063414a18.943211 18.943211 0 0 0-18.772552-18.943211z" fill="#333333" p-id="7167"></path><path d="M224.63064 771.935836h566.760385a4.266489 4.266489 0 0 1 4.735803 4.735803v227.958501a4.266489 4.266489 0 0 1-4.735803 4.735803H224.63064a4.266489 4.266489 0 0 1-4.735802-4.735803v-227.958501a4.266489 4.266489 0 0 1 4.735802-4.735803z" fill="#4A8BFD" p-id="7168"></path><path d="M781.876755 786.185909v209.057956H234.059581v-209.057956h547.817174m9.471605-28.414816H224.417316a18.943211 18.943211 0 0 0-18.943211 18.943211v227.915836a18.943211 18.943211 0 0 0 18.943211 18.943211h566.760385a18.943211 18.943211 0 0 0 18.943211-18.943211v-227.915836a18.943211 18.943211 0 0 0-18.772552-18.943211z m56.573643-251.722845a14.207408 14.207408 0 1 1 0-28.414816 147.577851 147.577851 0 0 0 0-295.113037 14.207408 14.207408 0 1 1 0-28.414816 175.992667 175.992667 0 0 1 0 351.985334z" fill="#333333" p-id="7169"></path><path d="M884.443148 530.751219a14.122078 14.122078 0 0 1-7.295696-2.00525l-41.512937-24.916295a14.207408 14.207408 0 0 1-1.791925-23.2097l41.512937-33.150619a14.207408 14.207408 0 0 1 17.705929 22.185743l-25.598934 20.393817 23.977668 14.420732a14.207408 14.207408 0 0 1-7.295696 26.452231z m-708.237157 326.215741a175.992667 175.992667 0 0 1 0-351.985334 14.207408 14.207408 0 0 1 0 28.414816 147.577851 147.577851 0 1 0 0 295.113037 14.207408 14.207408 0 0 1 0 28.414816z" fill="#333333" p-id="7170"></path><path d="M139.428857 881.413941a14.207408 14.207408 0 0 1-7.295696-26.452231l23.977668-14.420733-25.598934-20.393816a14.207408 14.207408 0 0 1 17.705929-22.185743l41.043623 33.662598a14.207408 14.207408 0 0 1-1.621265 23.295029l-41.512937 24.916295a14.079413 14.079413 0 0 1-6.698388 1.578601z" fill="#333333" p-id="7171"></path></svg>
|
After Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1703750094429"
|
||||
class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4262"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128">
|
||||
<path
|
||||
d="M512 0C229.312 0 0 229.312 0 512s229.312 512 512 512 512-229.312 512-512-229.312-512-512-512z m311.04 823.04a437.76 437.76 0 0 1-139.84 94.336c-54.208 23.04-111.808 34.624-171.2 34.624a439.36 439.36 0 0 1-311.04-128.896 437.76 437.76 0 0 1-94.336-139.904A435.776 435.776 0 0 1 72 512a439.36 439.36 0 0 1 128.896-311.04 437.76 437.76 0 0 1 139.904-94.336A435.776 435.776 0 0 1 512 72a439.36 439.36 0 0 1 311.04 128.896 437.76 437.76 0 0 1 94.336 139.904c23.04 54.208 34.624 111.808 34.624 171.2 0 59.392-11.584 116.992-34.56 171.2a436.096 436.096 0 0 1-94.336 139.904z"
|
||||
p-id="4263"></path>
|
||||
<path
|
||||
d="M701.824 436.992h-167.04c0.704 0 1.408-0.32 2.112-1.024l118.208-117.76a35.904 35.904 0 0 0-50.816-50.56L511.872 360.064l-92.864-92.8a36.16 36.16 0 0 0-51.136 0.192 36.16 36.16 0 0 0-0.064 51.072l118.208 118.08c0.64 0.704 1.408 1.728 2.112 1.728H321.6a34.688 34.688 0 0 0-34.304 34.56v3.2c0 18.816 15.488 33.856 34.304 33.856h154.368v64H353.536c-18.752 0-33.472 16.256-33.472 35.072v4.032c0 18.752 14.72 32.896 33.472 32.896h122.56v149.184a35.968 35.968 0 1 0 72 0v-149.184h121.792c18.752 0 35.2-14.08 35.2-32.896v-4.032a35.968 35.968 0 0 0-35.2-35.072H548.032v-64h153.792c18.752 0 35.2-14.208 35.2-33.088v-4.032a36.672 36.672 0 0 0-35.2-35.84z"
|
||||
p-id="4264"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@@ -113,8 +113,8 @@ const iconPaths = {
|
||||
'core/chat/speaking': () => import('./icons/core/chat/speaking.svg'),
|
||||
'core/chat/fileSelect': () => import('./icons/core/chat/fileSelect.svg'),
|
||||
'core/dataset/modeEmbedding': () => import('./icons/core/dataset/modeEmbedding.svg'),
|
||||
'core/dataset/modeEmbeddingRerank': () => import('./icons/core/dataset/modeEmbeddingRerank.svg'),
|
||||
'core/dataset/modeEmbFTRerank': () => import('./icons/core/dataset/modeEmbFTRerank.svg'),
|
||||
'core/dataset/fullTextRecall': () => import('./icons/core/dataset/fullTextRecall.svg'),
|
||||
'core/dataset/mixedRecall': () => import('./icons/core/dataset/mixedRecall.svg'),
|
||||
'core/app/variable/input': () => import('./icons/core/app/variable/input.svg'),
|
||||
'core/app/variable/textarea': () => import('./icons/core/app/variable/textarea.svg'),
|
||||
'core/app/variable/select': () => import('./icons/core/app/variable/select.svg'),
|
||||
@@ -125,7 +125,9 @@ const iconPaths = {
|
||||
'common/confirm/commonTip': () => import('./icons/common/confirm/commonTip.svg'),
|
||||
'common/routePushLight': () => import('./icons/common/routePushLight.svg'),
|
||||
'common/viewLight': () => import('./icons/common/viewLight.svg'),
|
||||
'core/app/customFeedback': () => import('./icons/core/app/customFeedback.svg')
|
||||
'core/app/customFeedback': () => import('./icons/core/app/customFeedback.svg'),
|
||||
'support/pay/priceLight': () => import('./icons/support/pay/priceLight.svg'),
|
||||
'core/dataset/rerank': () => import('./icons/core/dataset/rerank.svg')
|
||||
};
|
||||
|
||||
export type IconName = keyof typeof iconPaths;
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useToast } from '@chakra-ui/react';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
|
@@ -218,6 +218,9 @@
|
||||
.markdown blockquote > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.markdown table {
|
||||
width: 100%;
|
||||
}
|
||||
.markdown table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
44
projects/app/src/components/Select/SelectAiModel.tsx
Normal file
44
projects/app/src/components/Select/SelectAiModel.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import MySelect, { type SelectProps } from './index';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useDisclosure } from '@chakra-ui/react';
|
||||
const PriceBox = dynamic(() => import('@/components/support/wallet/Price'));
|
||||
|
||||
const SelectAiModel = ({ list, ...props }: SelectProps) => {
|
||||
const { t } = useTranslation();
|
||||
const expandList = useMemo(
|
||||
() =>
|
||||
list.concat({
|
||||
label: t('support.user.Price'),
|
||||
value: 'price'
|
||||
}),
|
||||
[list, t]
|
||||
);
|
||||
|
||||
const {
|
||||
isOpen: isOpenPriceBox,
|
||||
onOpen: onOpenPriceBox,
|
||||
onClose: onClosePriceBox
|
||||
} = useDisclosure();
|
||||
|
||||
return (
|
||||
<>
|
||||
<MySelect
|
||||
list={expandList}
|
||||
{...props}
|
||||
onchange={(e) => {
|
||||
if (e === 'price') {
|
||||
onOpenPriceBox();
|
||||
return;
|
||||
}
|
||||
props.onchange?.(e);
|
||||
}}
|
||||
/>
|
||||
{isOpenPriceBox && <PriceBox onClose={onClosePriceBox} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectAiModel;
|
@@ -1,17 +1,9 @@
|
||||
import React, { useRef, forwardRef, useMemo } from 'react';
|
||||
import {
|
||||
Menu,
|
||||
Box,
|
||||
MenuList,
|
||||
MenuItem,
|
||||
Button,
|
||||
useDisclosure,
|
||||
useOutsideClick,
|
||||
MenuButton
|
||||
} from '@chakra-ui/react';
|
||||
import { Menu, MenuList, MenuItem, Button, useDisclosure, MenuButton } from '@chakra-ui/react';
|
||||
import type { ButtonProps } from '@chakra-ui/react';
|
||||
import { ChevronDownIcon } from '@chakra-ui/icons';
|
||||
interface Props extends ButtonProps {
|
||||
|
||||
export type SelectProps = ButtonProps & {
|
||||
value?: string;
|
||||
placeholder?: string;
|
||||
list: {
|
||||
@@ -20,10 +12,10 @@ interface Props extends ButtonProps {
|
||||
value: string;
|
||||
}[];
|
||||
onchange?: (val: any) => void;
|
||||
}
|
||||
};
|
||||
|
||||
const MySelect = (
|
||||
{ placeholder, value, width = '100%', list, onchange, ...props }: Props,
|
||||
{ placeholder, value, width = '100%', list, onchange, ...props }: SelectProps,
|
||||
selectRef: any
|
||||
) => {
|
||||
const ref = useRef<HTMLButtonElement>(null);
|
||||
|
@@ -53,7 +53,7 @@ const SideTabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) =>
|
||||
cursor: 'pointer'
|
||||
})}
|
||||
_hover={{
|
||||
bg: 'myWhite.600'
|
||||
bg: 'myGray.05'
|
||||
}}
|
||||
onClick={() => {
|
||||
if (activeId === item.id) return;
|
||||
|
@@ -1,5 +1,15 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Box, Button, ModalBody, ModalFooter, Textarea } from '@chakra-ui/react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Checkbox,
|
||||
Divider,
|
||||
Flex,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
Textarea,
|
||||
useTheme
|
||||
} from '@chakra-ui/react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
import MySlider from '@/components/Slider';
|
||||
@@ -12,43 +22,58 @@ import { reRankModelList } from '@/web/common/system/staticData';
|
||||
import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||
import { DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constant';
|
||||
import MyRadio from '@/components/common/MyRadio';
|
||||
import MyIcon from '@/components/Icon';
|
||||
|
||||
type DatasetParamsProps = {
|
||||
similarity?: number;
|
||||
limit?: number;
|
||||
searchMode: `${DatasetSearchModeEnum}`;
|
||||
searchEmptyText?: string;
|
||||
limit?: number;
|
||||
similarity?: number;
|
||||
usingReRank?: boolean;
|
||||
maxTokens?: number;
|
||||
};
|
||||
|
||||
const DatasetParamsModal = ({
|
||||
searchMode = DatasetSearchModeEnum.embedding,
|
||||
searchEmptyText,
|
||||
limit,
|
||||
similarity,
|
||||
searchMode = DatasetSearchModeEnum.embedding,
|
||||
usingReRank,
|
||||
maxTokens = 3000,
|
||||
onClose,
|
||||
onSuccess
|
||||
}: DatasetParamsProps & { onClose: () => void; onSuccess: (e: DatasetParamsProps) => void }) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const { register, setValue, getValues, handleSubmit } = useForm<DatasetParamsProps>({
|
||||
defaultValues: {
|
||||
searchEmptyText,
|
||||
limit,
|
||||
similarity,
|
||||
searchMode
|
||||
searchMode,
|
||||
usingReRank
|
||||
}
|
||||
});
|
||||
|
||||
const searchModeList = useMemo(() => {
|
||||
const list = Object.values(DatasetSearchModeMap);
|
||||
if (reRankModelList.length > 0) {
|
||||
return list;
|
||||
}
|
||||
return list.slice(0, 1);
|
||||
return list;
|
||||
}, []);
|
||||
|
||||
const showSimilarity = useMemo(() => {
|
||||
if (similarity === undefined) return false;
|
||||
if (
|
||||
getValues('searchMode') === DatasetSearchModeEnum.fullTextRecall &&
|
||||
!getValues('usingReRank')
|
||||
)
|
||||
return false;
|
||||
if (getValues('searchMode') === DatasetSearchModeEnum.mixedRecall && !getValues('usingReRank'))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}, [getValues, similarity, refresh]);
|
||||
|
||||
return (
|
||||
<MyModal
|
||||
isOpen={true}
|
||||
@@ -57,7 +82,6 @@ const DatasetParamsModal = ({
|
||||
title={t('core.dataset.search.Dataset Search Params')}
|
||||
w={['90vw', '550px']}
|
||||
h={['90vh', 'auto']}
|
||||
overflow={'unset'}
|
||||
isCentered={searchEmptyText !== undefined}
|
||||
>
|
||||
<ModalBody flex={['1 0 0', 'auto']} overflow={'auto'}>
|
||||
@@ -71,9 +95,73 @@ const DatasetParamsModal = ({
|
||||
setRefresh(!refresh);
|
||||
}}
|
||||
/>
|
||||
{usingReRank !== undefined && reRankModelList.length > 0 && (
|
||||
<>
|
||||
<Divider my={4} />
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
cursor={'pointer'}
|
||||
userSelect={'none'}
|
||||
py={3}
|
||||
pl={'14px'}
|
||||
pr={'16px'}
|
||||
border={theme.borders.sm}
|
||||
borderWidth={'1.5px'}
|
||||
borderRadius={'md'}
|
||||
position={'relative'}
|
||||
{...(getValues('usingReRank')
|
||||
? {
|
||||
borderColor: 'primary.400'
|
||||
}
|
||||
: {})}
|
||||
onClick={(e) => {
|
||||
setValue('usingReRank', !getValues('usingReRank'));
|
||||
setRefresh((state) => !state);
|
||||
}}
|
||||
>
|
||||
<MyIcon name="core/dataset/rerank" w={'18px'} mr={'14px'} />
|
||||
<Box pr={2} color={'myGray.800'} flex={'1 0 0'}>
|
||||
<Box>{t('core.dataset.search.ReRank')}</Box>
|
||||
<Box fontSize={['xs', 'sm']} color={'myGray.500'}>
|
||||
{t('core.dataset.search.ReRank desc')}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box position={'relative'} w={'18px'} h={'18px'}>
|
||||
<Checkbox colorScheme="primary" isChecked={getValues('usingReRank')} size="lg" />
|
||||
<Box position={'absolute'} top={0} right={0} bottom={0} left={0} zIndex={1}></Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
</>
|
||||
)}
|
||||
|
||||
{similarity !== undefined && (
|
||||
{limit !== undefined && (
|
||||
<Box display={['block', 'flex']} py={8} mt={3}>
|
||||
<Box flex={'0 0 100px'} mb={[8, 0]}>
|
||||
{t('core.dataset.search.Max Tokens')}
|
||||
<MyTooltip label={t('core.dataset.search.Max Tokens Tips')} forceShow>
|
||||
<QuestionOutlineIcon ml={1} />
|
||||
</MyTooltip>
|
||||
</Box>
|
||||
<Box flex={1} mx={4}>
|
||||
<MySlider
|
||||
markList={[
|
||||
{ label: '100', value: 100 },
|
||||
{ label: maxTokens, value: maxTokens }
|
||||
]}
|
||||
min={100}
|
||||
max={maxTokens}
|
||||
step={50}
|
||||
value={getValues(ModuleInputKeyEnum.datasetLimit) ?? 1000}
|
||||
onChange={(val) => {
|
||||
setValue(ModuleInputKeyEnum.datasetLimit, val);
|
||||
setRefresh(!refresh);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
{showSimilarity && (
|
||||
<Box display={['block', 'flex']} py={8}>
|
||||
<Box flex={'0 0 100px'} mb={[8, 0]}>
|
||||
{t('core.dataset.search.Min Similarity')}
|
||||
<MyTooltip label={t('core.dataset.search.Min Similarity Tips')} forceShow>
|
||||
@@ -98,32 +186,7 @@ const DatasetParamsModal = ({
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
{limit !== undefined && (
|
||||
<Box display={['block', 'flex']} py={8}>
|
||||
<Box flex={'0 0 100px'} mb={[8, 0]}>
|
||||
{t('core.dataset.search.Max Tokens')}
|
||||
<MyTooltip label={t('core.dataset.search.Max Tokens Tips')} forceShow>
|
||||
<QuestionOutlineIcon ml={1} />
|
||||
</MyTooltip>
|
||||
</Box>
|
||||
<Box flex={1} mx={4}>
|
||||
<MySlider
|
||||
markList={[
|
||||
{ label: '300', value: 300 },
|
||||
{ label: maxTokens, value: maxTokens }
|
||||
]}
|
||||
min={300}
|
||||
max={maxTokens}
|
||||
step={10}
|
||||
value={getValues(ModuleInputKeyEnum.datasetLimit) ?? 1000}
|
||||
onChange={(val) => {
|
||||
setValue(ModuleInputKeyEnum.datasetLimit, val);
|
||||
setRefresh(!refresh);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{searchEmptyText !== undefined && (
|
||||
<Box display={['block', 'flex']} pt={3}>
|
||||
<Box flex={'0 0 100px'} mb={[2, 0]}>
|
||||
|
@@ -8,7 +8,7 @@ import MySelect from '@/components/Select';
|
||||
import { TTSTypeEnum } from '@/constants/app';
|
||||
import type { AppTTSConfigType } from '@fastgpt/global/core/module/type.d';
|
||||
import { useAudioPlay } from '@/web/common/utils/voice';
|
||||
import { audioSpeechModels } from '@/web/common/system/staticData';
|
||||
import { audioSpeechModelList } from '@/web/common/system/staticData';
|
||||
import MyModal from '@/components/MyModal';
|
||||
import MySlider from '@/components/Slider';
|
||||
|
||||
@@ -26,7 +26,7 @@ const TTSSelect = ({
|
||||
() => [
|
||||
{ label: t('core.app.tts.Close'), value: TTSTypeEnum.none },
|
||||
{ label: t('core.app.tts.Web'), value: TTSTypeEnum.web },
|
||||
...audioSpeechModels.map((item) => item?.voices || []).flat()
|
||||
...audioSpeechModelList.map((item) => item?.voices || []).flat()
|
||||
],
|
||||
[t]
|
||||
);
|
||||
@@ -52,7 +52,7 @@ const TTSSelect = ({
|
||||
if (e === TTSTypeEnum.none || e === TTSTypeEnum.web) {
|
||||
onChange({ type: e as `${TTSTypeEnum}` });
|
||||
} else {
|
||||
const audioModel = audioSpeechModels.find(
|
||||
const audioModel = audioSpeechModelList.find(
|
||||
(item) => item.voices?.find((voice) => voice.value === e)
|
||||
);
|
||||
if (!audioModel) {
|
||||
|
@@ -1,10 +1,9 @@
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import type { RenderInputProps } from '../type';
|
||||
import { onChangeNode } from '../../../../FlowProvider';
|
||||
import MySelect from '@/components/Select';
|
||||
import SelectAiModel from '@/components/Select/SelectAiModel';
|
||||
import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||
import { chatModelList, cqModelList, extractModelList } from '@/web/common/system/staticData';
|
||||
import { formatPrice } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
|
||||
const SelectAiModelRender = ({ item, inputs = [], moduleId }: RenderInputProps) => {
|
||||
const modelList = (() => {
|
||||
@@ -16,8 +15,7 @@ const SelectAiModelRender = ({ item, inputs = [], moduleId }: RenderInputProps)
|
||||
})().map((item) => ({
|
||||
model: item.model,
|
||||
name: item.name,
|
||||
maxResponse: item.maxResponse,
|
||||
price: item.price
|
||||
maxResponse: item.maxResponse
|
||||
}));
|
||||
|
||||
const onChangeModel = useCallback(
|
||||
@@ -55,11 +53,9 @@ const SelectAiModelRender = ({ item, inputs = [], moduleId }: RenderInputProps)
|
||||
);
|
||||
|
||||
const list = modelList.map((item) => {
|
||||
const priceStr = `(${formatPrice(item.price, 1000)}元/1k Tokens)`;
|
||||
|
||||
return {
|
||||
value: item.model,
|
||||
label: `${item.name}${priceStr}`
|
||||
label: item.name
|
||||
};
|
||||
});
|
||||
|
||||
@@ -70,7 +66,7 @@ const SelectAiModelRender = ({ item, inputs = [], moduleId }: RenderInputProps)
|
||||
}, [item.value, list, onChangeModel]);
|
||||
|
||||
return (
|
||||
<MySelect
|
||||
<SelectAiModel
|
||||
minW={'350px'}
|
||||
width={'100%'}
|
||||
value={item.value}
|
||||
|
@@ -17,7 +17,8 @@ const SelectDatasetParam = ({ inputs = [], moduleId }: RenderInputProps) => {
|
||||
const [data, setData] = useState({
|
||||
searchMode: DatasetSearchModeEnum.embedding,
|
||||
limit: 5,
|
||||
similarity: 0.5
|
||||
similarity: 0.5,
|
||||
usingReRank: false
|
||||
});
|
||||
|
||||
const tokenLimit = useMemo(() => {
|
||||
|
@@ -72,7 +72,7 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => {
|
||||
} = useQuery(['getOpenApiKeys', appId], () => getOpenApiKeys({ appId }));
|
||||
|
||||
useEffect(() => {
|
||||
setBaseUrl(`${location.origin}/api`);
|
||||
setBaseUrl(feConfigs?.customApiDomain || `${location.origin}/api`);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@@ -255,7 +255,7 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => {
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button variant="whiteBase" onClick={() => setApiKey('')}>
|
||||
好的
|
||||
{t('common.OK')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</MyModal>
|
||||
|
168
projects/app/src/components/support/wallet/Price.tsx
Normal file
168
projects/app/src/components/support/wallet/Price.tsx
Normal file
@@ -0,0 +1,168 @@
|
||||
import React from 'react';
|
||||
import { Box, CloseButton } from '@chakra-ui/react';
|
||||
import {
|
||||
chatModelList,
|
||||
vectorModelList,
|
||||
qaModelList,
|
||||
cqModelList,
|
||||
extractModelList,
|
||||
qgModelList,
|
||||
audioSpeechModelList,
|
||||
reRankModelList,
|
||||
whisperModel
|
||||
} from '@/web/common/system/staticData';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import Markdown from '@/components/Markdown';
|
||||
|
||||
const Price = ({ onClose }: { onClose: () => void }) => {
|
||||
const list = [
|
||||
{
|
||||
title: '知识库存储',
|
||||
describe: '',
|
||||
md: `
|
||||
| 计费项 | 价格(¥) |
|
||||
| --- | --- |
|
||||
| 知识库索引数量 | 0/1000条/天 |`
|
||||
},
|
||||
{
|
||||
title: '对话模型',
|
||||
describe: '',
|
||||
md: `
|
||||
| 模型 | 输入价格(¥) | 输出价格(¥) |
|
||||
| --- | --- | --- |
|
||||
${chatModelList
|
||||
?.map((item) => `| ${item.name} | ${item.inputPrice}/1k tokens | ${item.outputPrice}/1k tokens |`)
|
||||
.join('\n')}`
|
||||
},
|
||||
{
|
||||
title: '索引模型(文档训练 & 文档检索)',
|
||||
describe: '',
|
||||
md: `
|
||||
| 模型 | 价格(¥) |
|
||||
| --- | --- |
|
||||
${vectorModelList?.map((item) => `| ${item.name} | ${item.inputPrice}/1k tokens |`).join('\n')}
|
||||
`
|
||||
},
|
||||
{
|
||||
title: '文件预处理模型(QA 拆分)',
|
||||
describe: '',
|
||||
md: `
|
||||
| 模型 | 输入价格(¥) | 输出价格(¥) |
|
||||
| --- | --- | --- |
|
||||
${qaModelList
|
||||
?.map(
|
||||
(item) => `| ${item.name} | ${item.inputPrice}/1k tokens | ${item.outputPrice}/1k tokens |`
|
||||
)
|
||||
.join('\n')}
|
||||
`
|
||||
},
|
||||
{
|
||||
title: '问题分类',
|
||||
describe: '',
|
||||
md: `
|
||||
| 模型 | 输入价格(¥) | 输出价格(¥) |
|
||||
| --- | --- | --- |
|
||||
${cqModelList
|
||||
?.map(
|
||||
(item) => `| ${item.name} | ${item.inputPrice}/1k tokens | ${item.outputPrice}/1k tokens |`
|
||||
)
|
||||
.join('\n')}`
|
||||
},
|
||||
{
|
||||
title: '内容提取',
|
||||
describe: '',
|
||||
md: `
|
||||
| 模型 | 输入价格(¥) | 输出价格(¥) |
|
||||
| --- | --- | --- |
|
||||
${extractModelList
|
||||
?.map(
|
||||
(item) => `| ${item.name} | ${item.inputPrice}/1k tokens | ${item.outputPrice}/1k tokens |`
|
||||
)
|
||||
.join('\n')}`
|
||||
},
|
||||
{
|
||||
title: '下一步指引',
|
||||
describe: '',
|
||||
md: `
|
||||
| 模型 | 输入价格(¥) | 输出价格(¥) |
|
||||
| --- | --- | --- |
|
||||
${qgModelList
|
||||
?.map(
|
||||
(item) => `| ${item.name} | ${item.inputPrice}/1k tokens | ${item.outputPrice}/1k tokens |`
|
||||
)
|
||||
.join('\n')}`
|
||||
},
|
||||
{
|
||||
title: '重排模型(增强检索 & 混合检索)',
|
||||
describe: '',
|
||||
md: `
|
||||
| 模型 | 价格(¥) |
|
||||
| --- | --- |
|
||||
${reRankModelList?.map((item) => `| ${item.name} | ${item.inputPrice}/1k 字符 |`).join('\n')}`
|
||||
},
|
||||
{
|
||||
title: '语音播放',
|
||||
describe: '',
|
||||
md: `
|
||||
| 模型 | 价格(¥) |
|
||||
| --- | --- |
|
||||
${audioSpeechModelList
|
||||
?.map((item) => `| ${item.name} | ${item.inputPrice}/1k 字符 | - |`)
|
||||
.join('\n')}`
|
||||
},
|
||||
...(whisperModel
|
||||
? [
|
||||
{
|
||||
title: '语音输入',
|
||||
describe: '',
|
||||
md: `
|
||||
| 模型 | 价格(¥) |
|
||||
| --- | --- |
|
||||
| ${whisperModel.name} | ${whisperModel.inputPrice}/分钟 | - |`
|
||||
}
|
||||
]
|
||||
: [])
|
||||
];
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
<Box position={'fixed'} top={0} right={0} bottom={0} left={0} zIndex={99999} bg={'white'}>
|
||||
<CloseButton
|
||||
position={'absolute'}
|
||||
top={'10px'}
|
||||
right={'20px'}
|
||||
bg={'myGray.200'}
|
||||
w={'30px'}
|
||||
h={'30px'}
|
||||
borderRadius={'50%'}
|
||||
onClick={onClose}
|
||||
/>
|
||||
<Box py={[0, 10]} px={[5, '50px']} overflow={'overlay'} h={'100%'}>
|
||||
{list.map((item) => (
|
||||
<Box
|
||||
display={['block', 'flex']}
|
||||
key={item.title}
|
||||
w={'100%'}
|
||||
mb={4}
|
||||
pb={6}
|
||||
_notLast={{
|
||||
borderBottom: '1px',
|
||||
borderBottomColor: 'borderColor.high'
|
||||
}}
|
||||
>
|
||||
<Box fontSize={'xl'} fontWeight={'bold'} mb={1} flex={'1 0 0'}>
|
||||
{item.title}
|
||||
</Box>
|
||||
<Box w={['100%', '410px']}>
|
||||
<Markdown source={item.md}></Markdown>
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</Box>,
|
||||
// @ts-ignore
|
||||
document.querySelector('body')
|
||||
);
|
||||
};
|
||||
|
||||
export default Price;
|
Reference in New Issue
Block a user