V4.8.17 feature (#3485)

* feat: add third party account config (#3443)

* temp

* editor workflow variable style

* add team to dispatch

* i18n

* delete console

* change openai account position

* fix

* fix

* fix

* fix

* fix

* 4.8.17 test (#3461)

* perf: external provider config

* perf: ui

* feat: add template config (#3434)

* change template position

* template config

* delete console

* delete

* fix

* fix

* perf: Mongo visutal field (#3464)

* remve invalid code

* perf: team member visutal code

* perf: virtual search; perf: search test data

* fix: ts

* fix: image response headers

* perf: template code

* perf: auth layout;perf: auto save (#3472)

* perf: auth layout

* perf: auto save

* perf: auto save

* fix: template guide display & http input support external variables (#3475)

* fix: template guide display

* http editor support external workflow variables

* perf: auto save;fix: ifelse checker line break; (#3478)

* perf: auto save

* perf: auto save

* fix: ifelse checker line break

* perf: doc

* perf: doc

* fix: update var type error

* 4.8.17 test (#3479)

* perf: auto save

* perf: auto save

* perf: template code

* 4.8.17 test (#3480)

* perf: auto save

* perf: auto save

* perf: model price model

* feat: add react memo

* perf: model provider filter

* fix: ts (#3481)

* perf: auto save

* perf: auto save

* fix: ts

* simple app tool select (#3473)

* workflow plugin userguide & simple tool ui

* simple tool filter

* reuse component

* change component to hook

* fix

* perf: too selector modal (#3484)

* perf: auto save

* perf: auto save

* perf: markdown render

* perf: too selector

* fix: app version require tmbId

* perf: templates refresh

* perf: templates refresh

* hide auto save error tip

* perf: toolkit guide

---------

Co-authored-by: heheer <heheer@sealos.io>
This commit is contained in:
Archer
2024-12-27 20:05:12 +08:00
committed by GitHub
parent a209856d48
commit b520988c64
207 changed files with 2943 additions and 1378 deletions

View File

@@ -17,7 +17,7 @@ const unAuthPage: { [key: string]: boolean } = {
'/price': true
};
const Auth = ({ children }: { children: JSX.Element }) => {
const Auth = ({ children }: { children: JSX.Element | React.ReactNode }) => {
const { t } = useTranslation();
const router = useRouter();
const { toast } = useToast();

View File

@@ -80,14 +80,14 @@ const Layout = ({ children }: { children: JSX.Element }) => {
{isHideNavbar ? (
<Auth>{children}</Auth>
) : (
<>
<Auth>
<Box h={'100%'} position={'fixed'} left={0} top={0} w={navbarWidth}>
<Navbar unread={unread} />
</Box>
<Box h={'100%'} ml={navbarWidth} overflow={'overlay'}>
<Auth>{children}</Auth>
{children}
</Box>
</>
</Auth>
)}
</>
)}
@@ -96,14 +96,16 @@ const Layout = ({ children }: { children: JSX.Element }) => {
{phoneUnShowLayoutRoute[router.pathname] || isChatPage ? (
<Auth>{children}</Auth>
) : (
<Flex h={'100%'} flexDirection={'column'}>
<Box flex={'1 0 0'} h={0}>
<Auth>{children}</Auth>
</Box>
<Box h={'50px'} borderTop={'1px solid rgba(0,0,0,0.1)'}>
<NavbarPhone unread={unread} />
</Box>
</Flex>
<Auth>
<Flex h={'100%'} flexDirection={'column'}>
<Box flex={'1 0 0'} h={0}>
{children}
</Box>
<Box h={'50px'} borderTop={'1px solid rgba(0,0,0,0.1)'}>
<NavbarPhone unread={unread} />
</Box>
</Flex>
</Auth>
)}
</>
)}

View File

@@ -82,6 +82,7 @@ const Navbar = ({ unread }: { unread: number }) => {
'/account/info',
'/account/team',
'/account/usage',
'/account/thirdParty',
'/account/apikey',
'/account/setting',
'/account/inform',

View File

@@ -28,17 +28,22 @@ const IframeHtmlCodeBlock = dynamic(() => import('./codeBlock/iframe-html'), { s
const ChatGuide = dynamic(() => import('./chat/Guide'), { ssr: false });
const QuestionGuide = dynamic(() => import('./chat/QuestionGuide'), { ssr: false });
const Markdown = ({
source = '',
showAnimation = false,
isDisabled = false,
forbidZhFormat = false
}: {
type Props = {
source?: string;
showAnimation?: boolean;
isDisabled?: boolean;
forbidZhFormat?: boolean;
}) => {
};
const Markdown = (props: Props) => {
const source = props.source || '';
if (source.length < 200000) {
return <MarkdownRender {...props} />;
}
return <Box whiteSpace={'pre-wrap'}>{source}</Box>;
};
const MarkdownRender = ({ source = '', showAnimation, isDisabled, forbidZhFormat }: Props) => {
const components = useMemo<any>(
() => ({
img: Image,

View File

@@ -24,12 +24,6 @@ const OneRowSelector = ({ list, onchange, disableTip, ...props }: Props) => {
const { t } = useTranslation();
const { feConfigs, llmModelList, vectorModelList } = useSystemStore();
const {
isOpen: isOpenAiPointsModal,
onClose: onCloseAiPointsModal,
onOpen: onOpenAiPointsModal
} = useDisclosure();
const avatarSize = useMemo(() => {
const size = {
sm: '1rem',
@@ -74,17 +68,6 @@ const OneRowSelector = ({ list, onchange, disableTip, ...props }: Props) => {
: avatarList;
}, [feConfigs.show_pay, avatarList, avatarSize, t]);
const onSelect = useCallback(
(e: string) => {
if (e === 'price') {
onOpenAiPointsModal();
return;
}
return onchange?.(e);
},
[onOpenAiPointsModal, onchange]
);
return (
<Box
css={{
@@ -94,30 +77,32 @@ const OneRowSelector = ({ list, onchange, disableTip, ...props }: Props) => {
}}
>
<MyTooltip label={disableTip}>
<MySelect
className="nowheel"
isDisabled={!!disableTip}
list={expandList}
{...props}
onchange={onSelect}
/>
<ModelPriceModal>
{({ onOpen }) => (
<MySelect
className="nowheel"
isDisabled={!!disableTip}
list={expandList}
{...props}
onchange={(e) => {
if (e === 'price') {
onOpen();
return;
}
return onchange?.(e);
}}
/>
)}
</ModelPriceModal>
</MyTooltip>
{isOpenAiPointsModal && <ModelPriceModal onClose={onCloseAiPointsModal} />}
</Box>
);
};
const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) => {
const { t } = useTranslation();
const { feConfigs, llmModelList, vectorModelList } = useSystemStore();
const { llmModelList, vectorModelList } = useSystemStore();
const [value, setValue] = useState<string[]>([]);
const {
isOpen: isOpenAiPointsModal,
onClose: onCloseAiPointsModal,
onOpen: onOpenAiPointsModal
} = useDisclosure();
const avatarSize = useMemo(() => {
const size = {
sm: '1rem',
@@ -211,8 +196,6 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) =>
}}
/>
</MyTooltip>
{isOpenAiPointsModal && <ModelPriceModal onClose={onCloseAiPointsModal} />}
</Box>
);
};

View File

@@ -0,0 +1,46 @@
import { Box, ModalBody, useDisclosure } from '@chakra-ui/react';
import Markdown from '@/components/Markdown';
import MyModal from '@fastgpt/web/components/common/MyModal';
import { getDocPath } from '@/web/common/system/doc';
import React from 'react';
const UseGuideModal = ({
children,
title,
iconSrc,
text,
link
}: {
children: ({ onClick }: { onClick: () => void }) => React.ReactNode;
title?: string;
iconSrc?: string;
text?: string;
link?: string;
}) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const onClick = () => {
if (link) {
return window.open(getDocPath(link), '_blank');
}
if (text) {
return onOpen();
}
};
return (
<>
{children({ onClick })}
{isOpen && (
<MyModal isOpen iconSrc={iconSrc} title={title} onClose={onClose} minW={'600px'}>
<ModalBody>
<Box border={'base'} borderRadius={'10px'} p={4} minH={'500px'}>
<Markdown source={text} />
</Box>
</ModalBody>
</MyModal>
)}
</>
);
};
export default React.memo(UseGuideModal);

View File

@@ -100,12 +100,6 @@ const AIChatSettingsModal = ({
setRefresh(!refresh);
};
const {
isOpen: isOpenAiPointsModal,
onClose: onCloseAiPointsModal,
onOpen: onOpenAiPointsModal
} = useDisclosure();
return (
<MyModal
isOpen
@@ -160,10 +154,11 @@ const AIChatSettingsModal = ({
<Th fontSize={'mini'} pb={2}>
<HStack spacing={1}>
<Box> {t('app:ai_point_price')}</Box>
<QuestionTip
label={t('app:look_ai_point_price')}
onClick={onOpenAiPointsModal}
/>
<ModelPriceModal>
{({ onOpen }) => (
<QuestionTip label={t('app:look_ai_point_price')} onClick={onOpen} />
)}
</ModelPriceModal>
</HStack>
</Th>
<Th fontSize={'mini'} pb={2}>
@@ -327,8 +322,6 @@ const AIChatSettingsModal = ({
{t('common:common.Confirm')}
</Button>
</ModalFooter>
{isOpenAiPointsModal && <ModelPriceModal onClose={onCloseAiPointsModal} />}
</MyModal>
);
};

View File

@@ -9,9 +9,9 @@ import {
Td,
Th,
Thead,
Tr
Tr,
useDisclosure
} from '@chakra-ui/react';
import MyModal from '@fastgpt/web/components/common/MyModal';
import { useTranslation } from 'next-i18next';
import React, { useMemo, useRef, useState } from 'react';
import {
@@ -26,6 +26,9 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
import Avatar from '@fastgpt/web/components/common/Avatar';
import MyTag from '@fastgpt/web/components/common/Tag/index';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import dynamic from 'next/dynamic';
const MyModal = dynamic(() => import('@fastgpt/web/components/common/MyModal'));
const ModelTable = () => {
const { t } = useTranslation();
@@ -156,6 +159,19 @@ const ModelTable = () => {
search
]);
const filterProviderList = useMemo(() => {
const allProviderIds: string[] = [
...llmModelList,
...vectorModelList,
...audioSpeechModelList,
whisperModel
].map((model) => model.provider);
return providerList.current.filter(
(item) => allProviderIds.includes(item.value) || item.value === ''
);
}, [audioSpeechModelList, llmModelList, vectorModelList, whisperModel]);
return (
<Flex flexDirection={'column'} h={'100%'}>
<Flex>
@@ -168,7 +184,7 @@ const ModelTable = () => {
bg={'myGray.50'}
value={provider}
onchange={setProvider}
list={providerList.current}
list={filterProviderList}
/>
</HStack>
<HStack flexShrink={0} ml={6}>
@@ -228,24 +244,34 @@ const ModelTable = () => {
export default ModelTable;
export const ModelPriceModal = ({ onClose }: { onClose: () => void }) => {
export const ModelPriceModal = ({
children
}: {
children: ({ onOpen }: { onOpen: () => void }) => React.ReactNode;
}) => {
const { t } = useTranslation();
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<MyModal
isCentered
iconSrc="/imgs/modal/bill.svg"
title={t('common:support.wallet.subscription.Ai points')}
isOpen
onClose={onClose}
w={'100%'}
h={'100%'}
maxW={'90vw'}
maxH={'90vh'}
>
<ModalBody flex={'1 0 0'}>
<ModelTable />
</ModalBody>
</MyModal>
<>
{children({ onOpen })}
{isOpen && (
<MyModal
isCentered
iconSrc="/imgs/modal/bill.svg"
title={t('common:support.wallet.subscription.Ai points')}
isOpen
onClose={onClose}
w={'100%'}
h={'100%'}
maxW={'90vw'}
maxH={'90vh'}
>
<ModalBody flex={'1 0 0'}>
<ModelTable />
</ModalBody>
</MyModal>
)}
</>
);
};

View File

@@ -226,8 +226,8 @@ const DatasetParamsModal = ({
{limit !== undefined && (
<Box display={['block', 'flex']}>
<Flex flex={'0 0 120px'} alignItems={'center'} mb={[5, 0]}>
<FormLabel>{t('app:max_quote_tokens')}</FormLabel>
<QuestionTip label={t('app:max_quote_tokens_tips')} />
<FormLabel>{t('common:max_quote_tokens')}</FormLabel>
<QuestionTip label={t('common:max_quote_tokens_tips')} />
</Flex>
<Box flex={'1 0 0'}>
<InputSlider
@@ -245,8 +245,8 @@ const DatasetParamsModal = ({
)}
<Box display={['block', 'flex']} mt={[6, 10]} mb={4}>
<Flex flex={'0 0 120px'} alignItems={'center'} mb={[5, 0]}>
<FormLabel>{t('app:min_similarity')}</FormLabel>
<QuestionTip label={t('app:min_similarity_tip')} />
<FormLabel>{t('common:min_similarity')}</FormLabel>
<QuestionTip label={t('common:min_similarity_tip')} />
</Flex>
<Box flex={'1 0 0'}>
{showSimilarity ? (

View File

@@ -1,4 +1,4 @@
import { Box, Button, Flex, Switch, Textarea } from '@chakra-ui/react';
import { Box, Button, Flex, Switch, Textarea, useDisclosure } from '@chakra-ui/react';
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io';
@@ -20,6 +20,8 @@ import { isEqual } from 'lodash';
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
import { ChatRecordContext } from '@/web/core/chat/context/chatRecordContext';
import { PluginRunContext } from '../context';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import AIModelSelector from '@/components/Select/AIModelSelector';
const JsonEditor = dynamic(() => import('@fastgpt/web/components/common/Textarea/JsonEditor'));
@@ -152,6 +154,7 @@ const RenderPluginInput = ({
}) => {
const { t } = useTranslation();
const inputType = input.renderTypeList[0];
const { llmModelList } = useSystemStore();
const render = (() => {
if (inputType === FlowNodeInputTypeEnum.customVariable) {
@@ -167,7 +170,19 @@ const RenderPluginInput = ({
<FileSelector onChange={onChange} input={input} setUploading={setUploading} value={value} />
);
}
if (inputType === FlowNodeInputTypeEnum.selectLLMModel) {
return (
<AIModelSelector
w={'100%'}
value={value}
list={llmModelList.map((item) => ({
value: item.model,
label: item.name
}))}
onchange={onChange}
/>
);
}
if (input.valueType === WorkflowIOValueTypeEnum.string) {
return (
<Textarea

View File

@@ -62,8 +62,8 @@ const SearchParamsTip = ({
<Thead>
<Tr bg={'transparent !important'}>
<Th fontSize={'mini'}>{t('common:core.dataset.search.search mode')}</Th>
<Th fontSize={'mini'}>{t('app:max_quote_tokens')}</Th>
<Th fontSize={'mini'}>{t('app:min_similarity')}</Th>
<Th fontSize={'mini'}>{t('common:max_quote_tokens')}</Th>
<Th fontSize={'mini'}>{t('common:min_similarity')}</Th>
{hasReRankModel && <Th fontSize={'mini'}>{t('common:core.dataset.search.ReRank')}</Th>}
<Th fontSize={'mini'}>{t('common:core.module.template.Query extension')}</Th>
{hasEmptyResponseMode && (

View File

@@ -96,7 +96,7 @@ const LafAccountModal = ({
});
return (
<MyModal isOpen iconSrc="/imgs/workflow/laf.png" title={t('common:user.Laf Account Setting')}>
<MyModal isOpen iconSrc="support/account/laf" title={t('common:user.Laf Account Setting')}>
<ModalBody>
<Box fontSize={'sm'} color={'myGray.500'}>
<Box>{t('common:support.user.Laf account intro')}</Box>
@@ -107,7 +107,7 @@ const LafAccountModal = ({
</Box>
<Box>
<Link textDecoration={'underline'} href={`${feConfigs.lafEnv}/`} isExternal>
{t('support.user.Go laf env', {
{t('common:support.user.Go laf env', {
env: feConfigs.lafEnv?.split('//')[1]
})}
</Link>

View File

@@ -2,7 +2,7 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
import { StandardSubLevelEnum, SubModeEnum } from '@fastgpt/global/support/wallet/sub/constants';
import React, { useMemo } from 'react';
import { standardSubLevelMap } from '@fastgpt/global/support/wallet/sub/constants';
import { Box, Flex, Grid, useDisclosure } from '@chakra-ui/react';
import { Box, Flex, Grid } from '@chakra-ui/react';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { useTranslation } from 'next-i18next';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
@@ -22,12 +22,6 @@ const StandardPlanContentList = ({
const { t } = useTranslation();
const { subPlans } = useSystemStore();
const {
isOpen: isOpenAiPointsModal,
onClose: onCloseAiPointsModal,
onOpen: onOpenAiPointsModal
} = useDisclosure();
const planContent = useMemo(() => {
const plan = subPlans?.standard?.[level];
@@ -100,11 +94,15 @@ const StandardPlanContentList = ({
amount: planContent.totalPoints
})}
</Box>
<QuestionTip
ml={1}
label={t('common:support.wallet.subscription.AI points click to read tip')}
onClick={onOpenAiPointsModal}
></QuestionTip>
<ModelPriceModal>
{({ onOpen }) => (
<QuestionTip
ml={1}
label={t('common:support.wallet.subscription.AI points click to read tip')}
onClick={onOpen}
/>
)}
</ModelPriceModal>
</Flex>
</Flex>
<Flex alignItems={'center'}>
@@ -127,7 +125,6 @@ const StandardPlanContentList = ({
<Box color={'myGray.600'}>{t('common:support.wallet.subscription.web_site_sync')}</Box>
</Flex>
)}
{isOpenAiPointsModal && <ModelPriceModal onClose={onCloseAiPointsModal} />}
</Grid>
) : null;
};