4.6.5- CoreferenceResolution Module (#631)

This commit is contained in:
Archer
2023-12-22 10:47:31 +08:00
committed by GitHub
parent 41115a96c0
commit cd682d4275
112 changed files with 4163 additions and 2700 deletions

View File

@@ -26,6 +26,43 @@ const QuoteModal = ({
isShare: boolean;
}) => {
const { t } = useTranslation();
return (
<>
<MyModal
isOpen={true}
onClose={onClose}
h={['90vh', '80vh']}
isCentered
minW={['90vw', '600px']}
iconSrc="/imgs/modal/quote.svg"
title={
<Box>
{t('core.chat.Quote Amount', { amount: rawSearch.length })}
<Box fontSize={'sm'} color={'myGray.500'} fontWeight={'normal'}>
{t('core.chat.quote.Quote Tip')}
</Box>
</Box>
}
>
<ModalBody whiteSpace={'pre-wrap'} textAlign={'justify'} wordBreak={'break-all'}>
<QuoteList rawSearch={rawSearch} isShare={isShare} />
</ModalBody>
</MyModal>
</>
);
};
export default QuoteModal;
export const QuoteList = React.memo(function QuoteList({
rawSearch = [],
isShare
}: {
rawSearch: SearchDataResponseItemType[];
isShare: boolean;
}) {
const { t } = useTranslation();
const { isPc } = useSystemStore();
const theme = useTheme();
const { toast } = useToast();
@@ -60,124 +97,104 @@ const QuoteModal = ({
return (
<>
<MyModal
isOpen={true}
onClose={onClose}
h={['90vh', '80vh']}
isCentered
minW={['90vw', '600px']}
iconSrc="/imgs/modal/quote.svg"
title={
<Box>
{t('core.chat.Quote Amount', { amount: rawSearch.length })}
<Box fontSize={'sm'} color={'myGray.500'} fontWeight={'normal'}>
{t('core.chat.quote.Quote Tip')}
</Box>
</Box>
}
>
<ModalBody whiteSpace={'pre-wrap'} textAlign={'justify'} wordBreak={'break-all'}>
{rawSearch.map((item, i) => (
<Box
key={i}
flex={'1 0 0'}
p={2}
borderRadius={'lg'}
border={theme.borders.base}
_notLast={{ mb: 2 }}
position={'relative'}
overflow={'hidden'}
_hover={{ '& .hover-data': { display: 'flex' } }}
bg={i % 2 === 0 ? 'white' : 'myWhite.500'}
>
<Flex alignItems={'flex-end'} mb={3} fontSize={'sm'}>
<RawSourceText
fontWeight={'bold'}
color={'black'}
sourceName={item.sourceName}
sourceId={item.sourceId}
canView={!isShare}
/>
<Box flex={1} />
{!isShare && (
<Link
as={NextLink}
className="hover-data"
display={'none'}
alignItems={'center'}
color={'blue.500'}
href={`/dataset/detail?datasetId=${item.datasetId}&currentTab=dataCard&collectionId=${item.collectionId}`}
>
{t('core.dataset.Go Dataset')}
<MyIcon name={'common/rightArrowLight'} w={'10px'} />
</Link>
)}
</Flex>
{rawSearch.map((item, i) => (
<Box
key={i}
flex={'1 0 0'}
p={2}
borderRadius={'lg'}
border={theme.borders.base}
_notLast={{ mb: 2 }}
position={'relative'}
overflow={'hidden'}
_hover={{ '& .hover-data': { display: 'flex' } }}
bg={i % 2 === 0 ? 'white' : 'myWhite.500'}
>
<Flex alignItems={'flex-end'} mb={3} fontSize={'sm'}>
<RawSourceText
fontWeight={'bold'}
color={'black'}
sourceName={item.sourceName}
sourceId={item.sourceId}
canView={!isShare}
/>
<Box flex={1} />
{!isShare && (
<Link
as={NextLink}
className="hover-data"
display={'none'}
alignItems={'center'}
color={'blue.500'}
href={`/dataset/detail?datasetId=${item.datasetId}&currentTab=dataCard&collectionId=${item.collectionId}`}
>
{t('core.dataset.Go Dataset')}
<MyIcon name={'common/rightArrowLight'} w={'10px'} />
</Link>
)}
</Flex>
<Box color={'black'}>{item.q}</Box>
<Box color={'myGray.600'}>{item.a}</Box>
{!isShare && (
<Flex alignItems={'center'} fontSize={'sm'} mt={3} gap={4} color={'myGray.500'}>
{isPc && (
<MyTooltip label={t('core.dataset.data.id')}>
<Flex border={theme.borders.base} py={'1px'} px={3} borderRadius={'3px'}>
# {item.id}
</Flex>
</MyTooltip>
)}
<MyTooltip label={t('core.dataset.Quote Length')}>
<Flex alignItems={'center'}>
<MyIcon name="common/text/t" w={'14px'} mr={1} color={'myGray.500'} />
{item.q.length + (item.a?.length || 0)}
</Flex>
</MyTooltip>
{!isShare && item.score && (
<MyTooltip label={t('core.dataset.Similarity')}>
<Flex alignItems={'center'}>
<MyIcon name={'kbTest'} w={'12px'} />
<Progress
mx={2}
w={['60px', '90px']}
value={item.score * 100}
size="sm"
borderRadius={'20px'}
colorScheme="myGray"
border={theme.borders.base}
/>
<Box>{item.score.toFixed(4)}</Box>
</Flex>
</MyTooltip>
)}
<Box flex={1} />
{item.id && (
<MyTooltip label={t('core.dataset.data.Edit')}>
<Box
bg={'rgba(255,255,255,0.9)'}
alignItems={'center'}
justifyContent={'center'}
boxShadow={'-10px 0 10px rgba(255,255,255,1)'}
>
<MyIcon
name={'edit'}
w={['16px', '18px']}
h={['16px', '18px']}
cursor={'pointer'}
color={'myGray.600'}
_hover={{
color: 'blue.600'
}}
onClick={() => onclickEdit(item)}
/>
</Box>
</MyTooltip>
)}
</Flex>
<Box color={'black'}>{item.q}</Box>
<Box color={'myGray.600'}>{item.a}</Box>
{!isShare && (
<Flex alignItems={'center'} fontSize={'sm'} mt={3} gap={4} color={'myGray.500'}>
{isPc && (
<MyTooltip label={t('core.dataset.data.id')}>
<Flex border={theme.borders.base} py={'1px'} px={3} borderRadius={'3px'}>
# {item.id}
</Flex>
</MyTooltip>
)}
</Box>
))}
</ModalBody>
<Loading fixed={false} />
</MyModal>
<MyTooltip label={t('core.dataset.Quote Length')}>
<Flex alignItems={'center'}>
<MyIcon name="common/text/t" w={'14px'} mr={1} color={'myGray.500'} />
{item.q.length + (item.a?.length || 0)}
</Flex>
</MyTooltip>
{!isShare && item.score && (
<MyTooltip label={t('core.dataset.Similarity')}>
<Flex alignItems={'center'}>
<MyIcon name={'kbTest'} w={'12px'} />
<Progress
mx={2}
w={['60px', '90px']}
value={item.score * 100}
size="sm"
borderRadius={'20px'}
colorScheme="myGray"
border={theme.borders.base}
/>
<Box>{item.score.toFixed(4)}</Box>
</Flex>
</MyTooltip>
)}
<Box flex={1} />
{item.id && (
<MyTooltip label={t('core.dataset.data.Edit')}>
<Box
bg={'rgba(255,255,255,0.9)'}
alignItems={'center'}
justifyContent={'center'}
boxShadow={'-10px 0 10px rgba(255,255,255,1)'}
>
<MyIcon
name={'edit'}
w={['16px', '18px']}
h={['16px', '18px']}
cursor={'pointer'}
color={'myGray.600'}
_hover={{
color: 'blue.600'
}}
onClick={() => onclickEdit(item)}
/>
</Box>
</MyTooltip>
)}
</Flex>
)}
</Box>
))}
{editInputData && editInputData.id && (
<InputDataModal
onClose={() => setEditInputData(undefined)}
@@ -191,8 +208,7 @@ const QuoteModal = ({
collectionId={editInputData.collectionId}
/>
)}
<Loading fixed={false} />
</>
);
};
export default QuoteModal;
});

View File

@@ -222,7 +222,11 @@ const ResponseTags = ({
<ContextModal context={contextModalData} onClose={() => setContextModalData(undefined)} />
)}
{isOpenWholeModal && (
<WholeResponseModal response={responseData} onClose={onCloseWholeModal} />
<WholeResponseModal
response={responseData}
isShare={isShare}
onClose={onCloseWholeModal}
/>
)}
</Flex>
</>

View File

@@ -3,13 +3,14 @@ import { Box, useTheme, Flex, Image } from '@chakra-ui/react';
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type.d';
import { useTranslation } from 'next-i18next';
import { moduleTemplatesFlat } from '@/web/core/modules/template/system';
import Tabs from '../Tabs';
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 Markdown from '../Markdown';
import { QuoteList } from './QuoteModal';
import { DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constant';
function Row({
@@ -37,7 +38,9 @@ function Row({
fontSize={'sm'}
{...(isCodeBlock
? { transform: 'translateY(-3px)' }
: { px: 3, py: 1, border: theme.borders.base })}
: value
? { px: 3, py: 1, border: theme.borders.base }
: {})}
>
{value && <Markdown source={strValue} />}
{rawDom}
@@ -48,13 +51,51 @@ function Row({
const WholeResponseModal = ({
response,
isShare,
onClose
}: {
response: ChatHistoryItemResType[];
isShare: boolean;
onClose: () => void;
}) => {
const { t } = useTranslation();
return (
<MyModal
isCentered
isOpen={true}
onClose={onClose}
h={['90vh', '80vh']}
minW={['90vw', '600px']}
iconSrc="/imgs/modal/wholeRecord.svg"
title={
<Flex alignItems={'center'}>
{t('chat.Complete Response')}
<MyTooltip label={'从左往右,为各个模块的响应顺序'}>
<QuestionOutlineIcon ml={2} />
</MyTooltip>
</Flex>
}
>
<Flex h={'100%'} flexDirection={'column'}>
<ResponseBox response={response} isShare={isShare} />
</Flex>
</MyModal>
);
};
export default WholeResponseModal;
const ResponseBox = React.memo(function ResponseBox({
response,
isShare
}: {
response: ChatHistoryItemResType[];
isShare: boolean;
}) {
const theme = useTheme();
const { t } = useTranslation();
const list = useMemo(
() =>
response.map((item, i) => ({
@@ -83,145 +124,129 @@ const WholeResponseModal = ({
const activeModule = useMemo(() => response[Number(currentTab)], [currentTab, response]);
return (
<MyModal
isCentered
isOpen={true}
onClose={onClose}
h={['90vh', '80vh']}
w={['90vw', '500px']}
iconSrc="/imgs/modal/wholeRecord.svg"
title={
<Flex alignItems={'center'}>
{t('chat.Complete Response')}
<MyTooltip label={'从左往右,为各个模块的响应顺序'}>
<QuestionOutlineIcon ml={2} />
</MyTooltip>
</Flex>
}
>
<Flex h={'100%'} flexDirection={'column'}>
<Box>
<Tabs list={list} activeId={currentTab} onChange={setCurrentTab} />
</Box>
<Box py={2} px={4} flex={'1 0 0'} overflow={'auto'}>
<Row label={t('core.chat.response.module name')} value={t(activeModule.moduleName)} />
{activeModule?.price !== undefined && (
<Row
label={t('core.chat.response.module price')}
value={`${formatPrice(activeModule?.price)}`}
/>
)}
<>
<Box>
<Tabs list={list} activeId={currentTab} onChange={setCurrentTab} />
</Box>
<Box py={2} px={4} flex={'1 0 0'} overflow={'auto'}>
<Row label={t('core.chat.response.module name')} value={t(activeModule.moduleName)} />
{activeModule?.price !== undefined && (
<Row
label={t('core.chat.response.module time')}
value={`${activeModule?.runningTime || 0}s`}
label={t('core.chat.response.module price')}
value={`${formatPrice(activeModule?.price)}`}
/>
<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('core.chat.response.module query')} value={activeModule?.query} />
)}
<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('core.chat.response.module query')} value={activeModule?.query} />
<Row
label={t('core.chat.response.context total length')}
value={activeModule?.contextTotalLen}
/>
{/* ai chat */}
<Row label={t('core.chat.response.module temperature')} value={activeModule?.temperature} />
<Row label={t('core.chat.response.module maxToken')} value={activeModule?.maxToken} />
<Row
label={t('core.chat.response.module historyPreview')}
rawDom={
activeModule.historyPreview ? (
<Box px={3} py={2} border={theme.borders.base} borderRadius={'md'}>
{activeModule.historyPreview?.map((item, i) => (
<Box
key={i}
_notLast={{
borderBottom: '1px solid',
borderBottomColor: 'myWhite.700',
mb: 2
}}
pb={2}
>
<Box fontWeight={'bold'}>{item.obj}</Box>
<Box whiteSpace={'pre-wrap'}>{item.value}</Box>
</Box>
))}
</Box>
) : (
''
)
}
/>
{activeModule.quoteList && activeModule.quoteList.length > 0 && (
<Row
label={t('core.chat.response.context total length')}
value={activeModule?.contextTotalLen}
label={t('core.chat.response.module quoteList')}
rawDom={<QuoteList isShare={isShare} rawSearch={activeModule.quoteList} />}
/>
)}
{/* ai chat */}
{/* dataset search */}
{activeModule?.searchMode && (
<Row
label={t('core.chat.response.module temperature')}
value={activeModule?.temperature}
label={t('core.dataset.search.search mode')}
// @ts-ignore
value={t(DatasetSearchModeMap[activeModule.searchMode]?.title)}
/>
<Row label={t('core.chat.response.module maxToken')} value={activeModule?.maxToken} />
)}
<Row label={t('core.chat.response.module similarity')} value={activeModule?.similarity} />
<Row label={t('core.chat.response.module limit')} value={activeModule?.limit} />
{/* classify question */}
<Row
label={t('core.chat.response.module cq')}
value={(() => {
if (!activeModule?.cqList) return '';
return activeModule.cqList.map((item) => `* ${item.value}`).join('\n');
})()}
/>
<Row label={t('core.chat.response.module cq result')} value={activeModule?.cqResult} />
{/* extract */}
<Row
label={t('core.chat.response.module extract description')}
value={activeModule?.extractDescription}
/>
{activeModule?.extractResult && (
<Row
label={t('core.chat.response.module historyPreview')}
rawDom={
activeModule.historyPreview ? (
<>
{activeModule.historyPreview?.map((item, i) => (
<Box
key={i}
_notLast={{
borderBottom: '1px solid',
borderBottomColor: 'myWhite.700',
mb: 2
}}
pb={2}
>
<Box fontWeight={'bold'}>{item.obj}</Box>
<Box whiteSpace={'pre-wrap'}>{item.value}</Box>
</Box>
))}
</>
) : (
''
)
}
label={t('core.chat.response.module extract result')}
value={`~~~json\n${JSON.stringify(activeModule?.extractResult, null, 2)}`}
/>
{activeModule.quoteList && activeModule.quoteList.length > 0 && (
<Row
label={t('core.chat.response.module quoteList')}
value={`~~~json\n${JSON.stringify(activeModule.quoteList, null, 2)}`}
/>
)}
)}
{/* dataset search */}
{activeModule?.searchMode && (
<Row
label={t('core.dataset.search.search mode')}
// @ts-ignore
value={t(DatasetSearchModeMap[activeModule.searchMode]?.title)}
/>
)}
<Row label={t('core.chat.response.module similarity')} value={activeModule?.similarity} />
<Row label={t('core.chat.response.module limit')} value={activeModule?.limit} />
{/* classify question */}
{/* http */}
{activeModule?.body && (
<Row
label={t('core.chat.response.module cq')}
value={(() => {
if (!activeModule?.cqList) return '';
return activeModule.cqList.map((item) => `* ${item.value}`).join('\n');
})()}
label={t('core.chat.response.module http body')}
value={`~~~json\n${JSON.stringify(activeModule?.body, null, 2)}`}
/>
<Row label={t('core.chat.response.module cq result')} value={activeModule?.cqResult} />
{/* extract */}
)}
{activeModule?.httpResult && (
<Row
label={t('core.chat.response.module extract description')}
value={activeModule?.extractDescription}
label={t('core.chat.response.module http result')}
value={`~~~json\n${JSON.stringify(activeModule?.httpResult, null, 2)}`}
/>
{activeModule?.extractResult && (
<Row
label={t('core.chat.response.module extract result')}
value={`~~~json\n${JSON.stringify(activeModule?.extractResult, null, 2)}`}
/>
)}
)}
{/* http */}
{activeModule?.body && (
<Row
label={t('core.chat.response.module http body')}
value={`~~~json\n${JSON.stringify(activeModule?.body, null, 2)}`}
/>
)}
{activeModule?.httpResult && (
<Row
label={t('core.chat.response.module http result')}
value={`~~~json\n${JSON.stringify(activeModule?.httpResult, null, 2)}`}
/>
)}
{/* plugin */}
{activeModule?.pluginDetail && activeModule?.pluginDetail.length > 0 && (
<Row
label={t('core.chat.response.Plugin Resonse Detail')}
rawDom={<ResponseBox response={activeModule.pluginDetail} isShare={isShare} />}
/>
)}
{activeModule?.pluginOutput && (
<Row
label={t('core.chat.response.plugin output')}
value={`~~~json\n${JSON.stringify(activeModule?.pluginOutput, null, 2)}`}
/>
)}
{/* plugin */}
{activeModule?.pluginOutput && (
<Row
label={t('core.chat.response.plugin output')}
value={`~~~json\n${JSON.stringify(activeModule?.pluginOutput, null, 2)}`}
/>
)}
{/* text editor */}
<Row label={t('core.chat.response.text output')} value={activeModule?.textOutput} />
</Box>
</Flex>
</MyModal>
{/* text output */}
<Row label={t('core.chat.response.text output')} value={activeModule?.textOutput} />
</Box>
</>
);
};
export default WholeResponseModal;
});

View File

@@ -349,7 +349,13 @@ const ChatBox = (
responseText,
isNewChat = false
} = await onStartChat({
chatList: newChatList,
chatList: newChatList.map((item) => ({
dataId: item.dataId,
obj: item.obj,
value: item.value,
status: item.status,
moduleName: item.moduleName
})),
messages,
controller: abortSignal,
generatingMessage,
@@ -386,7 +392,7 @@ const ChatBox = (
}, 100);
} catch (err: any) {
toast({
title: getErrText(err, '聊天出错了~'),
title: t(getErrText(err, 'core.chat.error.Chat error')),
status: 'error',
duration: 5000,
isClosable: true
@@ -419,7 +425,8 @@ const ChatBox = (
generatingMessage,
createQuestionGuide,
generatingScroll,
isPc
isPc,
t
]
);

View File

@@ -39,7 +39,7 @@ const Layout = ({ children }: { children: JSX.Element }) => {
const router = useRouter();
const { colorMode, setColorMode } = useColorMode();
const { Loading } = useLoading();
const { loading, setScreenWidth, isPc, loadGitStar } = useSystemStore();
const { loading, setScreenWidth, isPc } = useSystemStore();
const { userInfo } = useUserStore();
const isChatPage = useMemo(
@@ -61,12 +61,11 @@ const Layout = ({ children }: { children: JSX.Element }) => {
window.addEventListener('resize', resize);
resize();
loadGitStar();
return () => {
window.removeEventListener('resize', resize);
};
}, [loadGitStar, setScreenWidth]);
}, [setScreenWidth]);
const { data: unread = 0 } = useQuery(['getUnreadCount'], getUnreadCount, {
enabled: !!userInfo && !!feConfigs.isPlus,

View File

@@ -346,7 +346,7 @@
width: 100%;
* {
word-break: break-all;
word-break: break-word;
}
pre {

View File

@@ -19,49 +19,51 @@ type Props = TextareaProps & {
// variables: string[];
};
const PromptTextarea = (props: Props) => {
const ModalTextareaRef = useRef<HTMLTextAreaElement>(null);
const TextareaRef = useRef<HTMLTextAreaElement>(null);
const PromptTextarea = React.forwardRef<HTMLTextAreaElement, Props>(
function PromptTextarea(props, ref) {
const ModalTextareaRef = useRef<HTMLTextAreaElement>(null);
const TextareaRef = useRef<HTMLTextAreaElement>(null);
const { t } = useTranslation();
const { title = t('core.app.edit.Prompt Editor'), value, ...childProps } = props;
const { t } = useTranslation();
const { title = t('core.app.edit.Prompt Editor'), ...childProps } = props;
const { isOpen, onOpen, onClose } = useDisclosure();
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<>
<Editor textareaRef={TextareaRef} {...childProps} onOpenModal={onOpen} />
{isOpen && (
<MyModal iconSrc="/imgs/modal/edit.svg" title={title} isOpen onClose={onClose}>
<ModalBody>
<Editor
textareaRef={ModalTextareaRef}
{...childProps}
minH={'300px'}
maxH={'auto'}
minW={['100%', '512px']}
/>
</ModalBody>
<ModalFooter>
<Button
onClick={() => {
if (ModalTextareaRef.current && TextareaRef.current) {
TextareaRef.current.value = ModalTextareaRef.current.value;
}
return (
<>
<Editor textareaRef={TextareaRef} {...childProps} onOpenModal={onOpen} />
{isOpen && (
<MyModal iconSrc="/imgs/modal/edit.svg" title={title} isOpen onClose={onClose}>
<ModalBody>
<Editor
textareaRef={ModalTextareaRef}
{...childProps}
minH={'300px'}
maxH={'auto'}
minW={['100%', '512px']}
/>
</ModalBody>
<ModalFooter>
<Button
onClick={() => {
if (ModalTextareaRef.current && TextareaRef.current) {
TextareaRef.current.value = ModalTextareaRef.current.value;
}
onClose();
}}
>
{t('common.Confirm')}
</Button>
</ModalFooter>
</MyModal>
)}
</>
);
};
onClose();
}}
>
{t('common.Confirm')}
</Button>
</ModalFooter>
</MyModal>
)}
</>
);
}
);
export default PromptTextarea;
export default React.memo(PromptTextarea);
const Editor = React.memo(function Editor({
onOpenModal,
@@ -75,7 +77,7 @@ const Editor = React.memo(function Editor({
return (
<Box h={'100%'} w={'100%'} position={'relative'}>
<Textarea ref={textareaRef} wordBreak={'break-all'} maxW={'100%'} {...props} />
<Textarea ref={textareaRef} textAlign={'justify'} maxW={'100%'} {...props} />
{onOpenModal && (
<Box
zIndex={1}

View File

@@ -1,5 +1,11 @@
import React from 'react';
import { SmoothStepEdge, EdgeLabelRenderer, EdgeProps, getSmoothStepPath } from 'reactflow';
import {
BezierEdge,
getBezierPath,
EdgeLabelRenderer,
EdgeProps,
getSmoothStepPath
} from 'reactflow';
import { Flex } from '@chakra-ui/react';
import MyIcon from '@/components/Icon';
@@ -21,7 +27,7 @@ const ButtonEdge = (
style = {}
} = props;
const [edgePath, labelX, labelY] = getSmoothStepPath({
const [edgePath, labelX, labelY] = getBezierPath({
sourceX,
sourceY,
sourcePosition,
@@ -42,7 +48,7 @@ const ButtonEdge = (
return (
<>
<SmoothStepEdge {...props} style={edgeStyle} />
<BezierEdge {...props} style={edgeStyle} />
<EdgeLabelRenderer>
<Flex
alignItems={'center'}

View File

@@ -14,7 +14,7 @@ import 'reactflow/dist/style.css';
import type { ModuleItemType } from '@fastgpt/global/core/module/type.d';
const NodeSimple = dynamic(() => import('./components/nodes/NodeSimple'));
const nodeTypes = {
const nodeTypes: Record<`${FlowNodeTypeEnum}`, any> = {
[FlowNodeTypeEnum.userGuide]: dynamic(() => import('./components/nodes/NodeUserGuide')),
[FlowNodeTypeEnum.variable]: dynamic(() => import('./components/nodes/abandon/NodeVariable')),
[FlowNodeTypeEnum.questionInput]: dynamic(() => import('./components/nodes/NodeQuestionInput')),
@@ -28,7 +28,8 @@ const nodeTypes = {
[FlowNodeTypeEnum.runApp]: NodeSimple,
[FlowNodeTypeEnum.pluginInput]: dynamic(() => import('./components/nodes/NodePluginInput')),
[FlowNodeTypeEnum.pluginOutput]: dynamic(() => import('./components/nodes/NodePluginOutput')),
[FlowNodeTypeEnum.pluginModule]: NodeSimple
[FlowNodeTypeEnum.pluginModule]: NodeSimple,
[FlowNodeTypeEnum.cfr]: NodeSimple
};
const edgeTypes = {
[EDGE_TYPE]: ButtonEdge

View File

@@ -1,14 +1,16 @@
import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
import { FlowNodeOutputTargetItemType } from '@fastgpt/global/core/module/node/type';
import { FlowModuleItemType, ModuleItemType } from '@fastgpt/global/core/module/type';
import { type Node, type Edge } from 'reactflow';
export function flowNode2Modules({
export const flowNode2Modules = ({
nodes,
edges
}: {
nodes: Node<FlowModuleItemType, string | undefined>[];
edges: Edge<any>[];
}) {
}) => {
const modules: ModuleItemType[] = nodes.map((item) => ({
moduleId: item.data.moduleId,
name: item.data.name,
@@ -48,4 +50,19 @@ export function flowNode2Modules({
});
return modules;
}
};
export const filterExportModules = (modules: ModuleItemType[]) => {
modules.forEach((module) => {
// dataset - remove select dataset value
if (module.flowType === FlowNodeTypeEnum.datasetSearchNode) {
module.inputs.forEach((item) => {
if (item.key === ModuleInputKeyEnum.datasetSelectList) {
item.value = [];
}
});
}
});
return JSON.stringify(modules, null, 2);
};