perf: tool call check (#4818)
* i18n * tool call * fix: mcp create permission;Plugin unauth tip * fix: mcp create permission;Plugin unauth tip * fix: Cite modal permission * remove invalide cite * perf: prompt * filter fulltext search * fix: ts * fix: ts * fix: ts
This commit is contained in:
@@ -22,135 +22,184 @@ import { getCollectionSourceData } from '@fastgpt/global/core/dataset/collection
|
||||
import Markdown from '.';
|
||||
import { getSourceNameIcon } from '@fastgpt/global/core/dataset/utils';
|
||||
import { Types } from 'mongoose';
|
||||
import type { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
|
||||
import { useCreation } from 'ahooks';
|
||||
|
||||
const A = ({ children, chatAuthData, showAnimation, ...props }: any) => {
|
||||
export type AProps = {
|
||||
chatAuthData?: {
|
||||
appId: string;
|
||||
chatId: string;
|
||||
chatItemDataId: string;
|
||||
} & OutLinkChatAuthProps;
|
||||
onOpenCiteModal?: (e?: {
|
||||
collectionId?: string;
|
||||
sourceId?: string;
|
||||
sourceName?: string;
|
||||
datasetId?: string;
|
||||
quoteId?: string;
|
||||
}) => void;
|
||||
};
|
||||
|
||||
const EmptyHrefLink = function EmptyHrefLink({ content }: { content: string }) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<MyTooltip label={t('common:core.chat.markdown.Quick Question')}>
|
||||
<Button
|
||||
variant={'whitePrimary'}
|
||||
size={'xs'}
|
||||
borderRadius={'md'}
|
||||
my={1}
|
||||
onClick={() => eventBus.emit(EventNameEnum.sendQuestion, { text: content })}
|
||||
>
|
||||
{content}
|
||||
</Button>
|
||||
</MyTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const CiteLink = React.memo(function CiteLink({
|
||||
id,
|
||||
chatAuthData,
|
||||
onOpenCiteModal,
|
||||
showAnimation
|
||||
}: { id: string; showAnimation?: boolean } & AProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const content = useMemo(() => String(children), [children]);
|
||||
|
||||
if (!Types.ObjectId.isValid(id)) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const {
|
||||
data: datasetCiteData,
|
||||
loading,
|
||||
runAsync: getQuoteDataById
|
||||
} = useRequest2((id: string) => getQuoteData({ id, ...chatAuthData }), {
|
||||
manual: true
|
||||
});
|
||||
const sourceData = useMemo(
|
||||
() => getCollectionSourceData(datasetCiteData?.collection),
|
||||
[datasetCiteData?.collection]
|
||||
);
|
||||
const icon = useMemo(
|
||||
() => getSourceNameIcon({ sourceId: sourceData.sourceId, sourceName: sourceData.sourceName }),
|
||||
[sourceData]
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover
|
||||
isLazy
|
||||
direction="rtl"
|
||||
placement="bottom"
|
||||
strategy={'fixed'}
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
onOpen={() => {
|
||||
onOpen();
|
||||
if (showAnimation) return;
|
||||
getQuoteDataById(id);
|
||||
}}
|
||||
trigger={'hover'}
|
||||
gutter={4}
|
||||
>
|
||||
<PopoverTrigger>
|
||||
<Button variant={'unstyled'} minH={0} minW={0} h={'auto'}>
|
||||
<MyIcon
|
||||
name={'core/chat/quoteSign'}
|
||||
w={'1rem'}
|
||||
color={'primary.700'}
|
||||
cursor={'pointer'}
|
||||
/>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent boxShadow={'lg'} w={'500px'} maxW={'90vw'} py={4}>
|
||||
<MyBox isLoading={loading || showAnimation}>
|
||||
<PopoverArrow />
|
||||
<PopoverBody py={0} px={0} fontSize={'sm'}>
|
||||
<Flex px={4} pb={1} justifyContent={'space-between'}>
|
||||
<Box
|
||||
alignItems={'center'}
|
||||
fontSize={'xs'}
|
||||
border={'sm'}
|
||||
borderRadius={'sm'}
|
||||
overflow={'hidden'}
|
||||
display={'inline-flex'}
|
||||
height={6}
|
||||
mr={1}
|
||||
>
|
||||
<Flex px={1.5}>
|
||||
<MyIcon name={icon as any} mr={1} flexShrink={0} w={'12px'} />
|
||||
<Box
|
||||
className={'textEllipsis'}
|
||||
wordBreak={'break-all'}
|
||||
flex={'1 0 0'}
|
||||
fontSize={'mini'}
|
||||
color={'myGray.900'}
|
||||
>
|
||||
{sourceData.sourceName}
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
<Button
|
||||
variant={'ghost'}
|
||||
color={'primary.600'}
|
||||
size={'xs'}
|
||||
onClick={() => {
|
||||
onClose();
|
||||
onOpenCiteModal?.({
|
||||
quoteId: id,
|
||||
sourceId: sourceData.sourceId,
|
||||
sourceName: sourceData.sourceName,
|
||||
datasetId: datasetCiteData?.collection.datasetId,
|
||||
collectionId: datasetCiteData?.collection._id
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t('common:all_quotes')}
|
||||
</Button>
|
||||
</Flex>
|
||||
<Box h={'300px'} overflow={'auto'} px={4}>
|
||||
<Markdown source={datasetCiteData?.q} />
|
||||
{datasetCiteData?.a && <Markdown source={datasetCiteData?.a} />}
|
||||
</Box>
|
||||
</PopoverBody>
|
||||
</MyBox>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
});
|
||||
|
||||
const A = ({
|
||||
children,
|
||||
chatAuthData,
|
||||
onOpenCiteModal,
|
||||
showAnimation,
|
||||
...props
|
||||
}: AProps & {
|
||||
children: any;
|
||||
showAnimation: boolean;
|
||||
[key: string]: any;
|
||||
}) => {
|
||||
const content = useCreation(() => String(children), [children]);
|
||||
|
||||
// empty href link
|
||||
if (!props.href && typeof children?.[0] === 'string') {
|
||||
return (
|
||||
<MyTooltip label={t('common:core.chat.markdown.Quick Question')}>
|
||||
<Button
|
||||
variant={'whitePrimary'}
|
||||
size={'xs'}
|
||||
borderRadius={'md'}
|
||||
my={1}
|
||||
onClick={() => eventBus.emit(EventNameEnum.sendQuestion, { text: content })}
|
||||
>
|
||||
{content}
|
||||
</Button>
|
||||
</MyTooltip>
|
||||
);
|
||||
return <EmptyHrefLink content={content} />;
|
||||
}
|
||||
|
||||
// Cite
|
||||
if (
|
||||
(props.href?.startsWith('CITE') || props.href?.startsWith('QUOTE')) &&
|
||||
typeof children?.[0] === 'string'
|
||||
typeof content === 'string'
|
||||
) {
|
||||
if (!Types.ObjectId.isValid(content)) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const {
|
||||
data: quoteData,
|
||||
loading,
|
||||
runAsync: getQuoteDataById
|
||||
} = useRequest2((id: string) => getQuoteData({ id, ...chatAuthData }), {
|
||||
manual: true
|
||||
});
|
||||
const sourceData = useMemo(
|
||||
() => getCollectionSourceData(quoteData?.collection),
|
||||
[quoteData?.collection]
|
||||
);
|
||||
const icon = useMemo(
|
||||
() => getSourceNameIcon({ sourceId: sourceData.sourceId, sourceName: sourceData.sourceName }),
|
||||
[sourceData]
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover
|
||||
isLazy
|
||||
direction="rtl"
|
||||
placement="bottom"
|
||||
strategy={'fixed'}
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
onOpen={() => {
|
||||
onOpen();
|
||||
if (showAnimation) return;
|
||||
getQuoteDataById(String(children));
|
||||
}}
|
||||
trigger={'hover'}
|
||||
gutter={4}
|
||||
>
|
||||
<PopoverTrigger>
|
||||
<Button variant={'unstyled'} minH={0} minW={0} h={'auto'}>
|
||||
<MyIcon
|
||||
name={'core/chat/quoteSign'}
|
||||
w={'1rem'}
|
||||
color={'primary.700'}
|
||||
cursor={'pointer'}
|
||||
/>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent boxShadow={'lg'} w={'500px'} maxW={'90vw'} py={4}>
|
||||
<MyBox isLoading={loading || showAnimation}>
|
||||
<PopoverArrow />
|
||||
<PopoverBody py={0} px={0} fontSize={'sm'}>
|
||||
<Flex px={4} pb={1} justifyContent={'space-between'}>
|
||||
<Box
|
||||
alignItems={'center'}
|
||||
fontSize={'xs'}
|
||||
border={'sm'}
|
||||
borderRadius={'sm'}
|
||||
overflow={'hidden'}
|
||||
display={'inline-flex'}
|
||||
height={6}
|
||||
mr={1}
|
||||
>
|
||||
<Flex px={1.5}>
|
||||
<MyIcon name={icon as any} mr={1} flexShrink={0} w={'12px'} />
|
||||
<Box
|
||||
className={'textEllipsis'}
|
||||
wordBreak={'break-all'}
|
||||
flex={'1 0 0'}
|
||||
fontSize={'mini'}
|
||||
color={'myGray.900'}
|
||||
>
|
||||
{sourceData.sourceName}
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
<Button
|
||||
variant={'ghost'}
|
||||
color={'primary.600'}
|
||||
size={'xs'}
|
||||
onClick={() => {
|
||||
onClose();
|
||||
eventBus.emit(EventNameEnum.openQuoteReader, {
|
||||
quoteId: String(children),
|
||||
sourceId: sourceData.sourceId,
|
||||
sourceName: sourceData.sourceName,
|
||||
datasetId: quoteData?.collection.datasetId,
|
||||
collectionId: quoteData?.collection._id
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t('common:all_quotes')}
|
||||
</Button>
|
||||
</Flex>
|
||||
<Box h={'300px'} overflow={'auto'} px={4}>
|
||||
<Markdown source={quoteData?.q} />
|
||||
{quoteData?.a && <Markdown source={quoteData?.a} />}
|
||||
</Box>
|
||||
</PopoverBody>
|
||||
</MyBox>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<CiteLink
|
||||
id={content}
|
||||
chatAuthData={chatAuthData}
|
||||
onOpenCiteModal={onOpenCiteModal}
|
||||
showAnimation={showAnimation}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import dynamic from 'next/dynamic';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { CodeClassNameEnum, mdTextFormat } from './utils';
|
||||
import { useCreation } from 'ahooks';
|
||||
import { type OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
|
||||
import type { AProps } from './A';
|
||||
|
||||
const CodeLight = dynamic(() => import('./codeBlock/CodeLight'), { ssr: false });
|
||||
const MermaidCodeBlock = dynamic(() => import('./img/MermaidCodeBlock'), { ssr: false });
|
||||
@@ -33,12 +33,7 @@ type Props = {
|
||||
showAnimation?: boolean;
|
||||
isDisabled?: boolean;
|
||||
forbidZhFormat?: boolean;
|
||||
chatAuthData?: {
|
||||
appId: string;
|
||||
chatId: string;
|
||||
chatItemDataId: string;
|
||||
} & OutLinkChatAuthProps;
|
||||
};
|
||||
} & AProps;
|
||||
const Markdown = (props: Props) => {
|
||||
const source = props.source || '';
|
||||
|
||||
@@ -53,16 +48,25 @@ const MarkdownRender = ({
|
||||
showAnimation,
|
||||
isDisabled,
|
||||
forbidZhFormat,
|
||||
chatAuthData
|
||||
|
||||
chatAuthData,
|
||||
onOpenCiteModal
|
||||
}: Props) => {
|
||||
const components = useCreation(() => {
|
||||
return {
|
||||
img: Image,
|
||||
pre: RewritePre,
|
||||
code: Code,
|
||||
a: (props: any) => <A {...props} showAnimation={showAnimation} chatAuthData={chatAuthData} />
|
||||
a: (props: any) => (
|
||||
<A
|
||||
{...props}
|
||||
showAnimation={showAnimation}
|
||||
chatAuthData={chatAuthData}
|
||||
onOpenCiteModal={onOpenCiteModal}
|
||||
/>
|
||||
)
|
||||
};
|
||||
}, [chatAuthData, showAnimation]);
|
||||
}, [chatAuthData, onOpenCiteModal, showAnimation]);
|
||||
|
||||
const formatSource = useMemo(() => {
|
||||
if (showAnimation || forbidZhFormat) return source;
|
||||
|
||||
@@ -28,10 +28,15 @@ import { isEqual } from 'lodash';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import { formatTimeToChatItemTime } from '@fastgpt/global/common/string/time';
|
||||
import dayjs from 'dayjs';
|
||||
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
||||
import { eventBus, EventNameEnum } from '@/web/common/utils/eventbus';
|
||||
import {
|
||||
ChatItemContext,
|
||||
type OnOpenCiteModalProps
|
||||
} from '@/web/core/chat/context/chatItemContext';
|
||||
import { addStatisticalDataToHistoryItem } from '@/global/core/chat/utils';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
|
||||
const ResponseTags = dynamic(() => import('./ResponseTags'));
|
||||
|
||||
const colorMap = {
|
||||
[ChatStatusEnum.loading]: {
|
||||
@@ -88,13 +93,15 @@ const AIContentCard = React.memo(function AIContentCard({
|
||||
dataId,
|
||||
isLastChild,
|
||||
isChatting,
|
||||
questionGuides
|
||||
questionGuides,
|
||||
onOpenCiteModal
|
||||
}: {
|
||||
dataId: string;
|
||||
chatValue: ChatItemValueItemType[];
|
||||
isLastChild: boolean;
|
||||
isChatting: boolean;
|
||||
questionGuides: string[];
|
||||
onOpenCiteModal: (e?: OnOpenCiteModalProps) => void;
|
||||
}) {
|
||||
return (
|
||||
<Flex flexDirection={'column'} gap={2}>
|
||||
@@ -108,6 +115,7 @@ const AIContentCard = React.memo(function AIContentCard({
|
||||
value={value}
|
||||
isLastResponseValue={isLastChild && i === chatValue.length - 1}
|
||||
isChatting={isChatting}
|
||||
onOpenCiteModal={onOpenCiteModal}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@@ -122,7 +130,6 @@ const ChatItem = (props: Props) => {
|
||||
const { type, avatar, statusBoxData, children, isLastChild, questionGuides = [], chat } = props;
|
||||
|
||||
const { isPc } = useSystem();
|
||||
const { toast } = useToast();
|
||||
|
||||
const styleMap: BoxProps = {
|
||||
...(type === ChatRoleEnum.Human
|
||||
@@ -150,7 +157,6 @@ const ChatItem = (props: Props) => {
|
||||
const chatType = useContextSelector(ChatBoxContext, (v) => v.chatType);
|
||||
const showNodeStatus = useContextSelector(ChatItemContext, (v) => v.showNodeStatus);
|
||||
|
||||
const setQuoteData = useContextSelector(ChatItemContext, (v) => v.setQuoteData);
|
||||
const appId = useContextSelector(ChatBoxContext, (v) => v.appId);
|
||||
const chatId = useContextSelector(ChatBoxContext, (v) => v.chatId);
|
||||
const outLinkAuthData = useContextSelector(ChatBoxContext, (v) => v.outLinkAuthData);
|
||||
@@ -228,64 +234,48 @@ const ChatItem = (props: Props) => {
|
||||
return groupedValues;
|
||||
}, [chat.obj, chat.value, isChatting]);
|
||||
|
||||
const handleOpenQuoteReader = useCallback(
|
||||
({
|
||||
collectionId,
|
||||
sourceId,
|
||||
sourceName,
|
||||
datasetId,
|
||||
quoteId
|
||||
}: {
|
||||
const setCiteModalData = useContextSelector(ChatItemContext, (v) => v.setCiteModalData);
|
||||
const onOpenCiteModal = useMemoizedFn(
|
||||
(item?: {
|
||||
collectionId?: string;
|
||||
sourceId?: string;
|
||||
sourceName?: string;
|
||||
datasetId?: string;
|
||||
quoteId?: string;
|
||||
}) => {
|
||||
if (!setQuoteData) return;
|
||||
|
||||
const collectionIdList = collectionId
|
||||
? [collectionId]
|
||||
const collectionIdList = item?.collectionId
|
||||
? [item.collectionId]
|
||||
: [...new Set(quoteList.map((item) => item.collectionId))];
|
||||
|
||||
setQuoteData({
|
||||
setCiteModalData({
|
||||
rawSearch: quoteList,
|
||||
metadata:
|
||||
collectionId && isShowReadRawSource
|
||||
item?.collectionId && isShowReadRawSource
|
||||
? {
|
||||
appId: appId,
|
||||
chatId: chatId,
|
||||
chatItemDataId: chat.dataId,
|
||||
collectionId: collectionId,
|
||||
collectionId: item.collectionId,
|
||||
collectionIdList,
|
||||
sourceId: sourceId || '',
|
||||
sourceName: sourceName || '',
|
||||
datasetId: datasetId || '',
|
||||
sourceId: item.sourceId || '',
|
||||
sourceName: item.sourceName || '',
|
||||
datasetId: item.datasetId || '',
|
||||
outLinkAuthData,
|
||||
quoteId
|
||||
quoteId: item.quoteId
|
||||
}
|
||||
: {
|
||||
appId: appId,
|
||||
chatId: chatId,
|
||||
chatItemDataId: chat.dataId,
|
||||
collectionIdList,
|
||||
sourceId: sourceId,
|
||||
sourceName: sourceName,
|
||||
sourceId: item?.sourceId,
|
||||
sourceName: item?.sourceName,
|
||||
outLinkAuthData
|
||||
}
|
||||
});
|
||||
},
|
||||
[setQuoteData, quoteList, isShowReadRawSource, appId, chatId, chat.dataId, outLinkAuthData]
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (chat.obj !== ChatRoleEnum.AI) return;
|
||||
eventBus.on(EventNameEnum.openQuoteReader, handleOpenQuoteReader);
|
||||
return () => {
|
||||
eventBus.off(EventNameEnum.openQuoteReader);
|
||||
};
|
||||
}, [chat.obj, handleOpenQuoteReader]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
_hover={{
|
||||
@@ -362,13 +352,23 @@ const ChatItem = (props: Props) => {
|
||||
>
|
||||
{type === ChatRoleEnum.Human && <HumanContentCard chatValue={value} />}
|
||||
{type === ChatRoleEnum.AI && (
|
||||
<AIContentCard
|
||||
chatValue={value}
|
||||
dataId={chat.dataId}
|
||||
isLastChild={isLastChild && i === splitAiResponseResults.length - 1}
|
||||
isChatting={isChatting}
|
||||
questionGuides={questionGuides}
|
||||
/>
|
||||
<>
|
||||
<AIContentCard
|
||||
chatValue={value}
|
||||
dataId={chat.dataId}
|
||||
isLastChild={isLastChild && i === splitAiResponseResults.length - 1}
|
||||
isChatting={isChatting}
|
||||
questionGuides={questionGuides}
|
||||
onOpenCiteModal={onOpenCiteModal}
|
||||
/>
|
||||
{i === splitAiResponseResults.length - 1 && (
|
||||
<ResponseTags
|
||||
showTags={!isLastChild || !isChatting}
|
||||
historyItem={chat}
|
||||
onOpenCiteModal={onOpenCiteModal}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{/* Example: Response tags. A set of dialogs only needs to be displayed once*/}
|
||||
{i === splitAiResponseResults.length - 1 && <>{children}</>}
|
||||
|
||||
@@ -14,17 +14,24 @@ import { addStatisticalDataToHistoryItem } from '@/global/core/chat/utils';
|
||||
import { useSize } from 'ahooks';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { ChatBoxContext } from '../Provider';
|
||||
import { eventBus, EventNameEnum } from '@/web/common/utils/eventbus';
|
||||
|
||||
const ContextModal = dynamic(() => import('./ContextModal'));
|
||||
const WholeResponseModal = dynamic(() => import('../../../components/WholeResponseModal'));
|
||||
|
||||
const ResponseTags = ({
|
||||
showTags,
|
||||
historyItem
|
||||
historyItem,
|
||||
onOpenCiteModal
|
||||
}: {
|
||||
showTags: boolean;
|
||||
historyItem: ChatSiteItemType;
|
||||
onOpenCiteModal: (e?: {
|
||||
collectionId?: string;
|
||||
sourceId?: string;
|
||||
sourceName?: string;
|
||||
datasetId?: string;
|
||||
quoteId?: string;
|
||||
}) => void;
|
||||
}) => {
|
||||
const { isPc } = useSystem();
|
||||
const { t } = useTranslation();
|
||||
@@ -80,15 +87,6 @@ const ResponseTags = ({
|
||||
}));
|
||||
}, [quoteList]);
|
||||
|
||||
const openQuoteReader = (item?: {
|
||||
collectionId?: string;
|
||||
sourceId?: string;
|
||||
sourceName?: string;
|
||||
datasetId?: string;
|
||||
}) => {
|
||||
eventBus.emit(EventNameEnum.openQuoteReader, item);
|
||||
};
|
||||
|
||||
const notEmptyTags =
|
||||
quoteList.length > 0 ||
|
||||
(llmModuleAccount === 1 && notSharePage) ||
|
||||
@@ -161,7 +159,7 @@ const ResponseTags = ({
|
||||
cursor={'pointer'}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
openQuoteReader(item);
|
||||
onOpenCiteModal(item);
|
||||
}}
|
||||
height={6}
|
||||
>
|
||||
@@ -216,7 +214,7 @@ const ResponseTags = ({
|
||||
cursor={'pointer'}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
openQuoteReader();
|
||||
onOpenCiteModal();
|
||||
}}
|
||||
>
|
||||
{t('chat:citations', { num: quoteList.length })}
|
||||
|
||||
@@ -68,7 +68,6 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { valueTypeFormat } from '@fastgpt/global/core/workflow/runtime/utils';
|
||||
|
||||
const ResponseTags = dynamic(() => import('./components/ResponseTags'));
|
||||
const FeedbackModal = dynamic(() => import('./components/FeedbackModal'));
|
||||
const ReadFeedbackModal = dynamic(() => import('./components/ReadFeedbackModal'));
|
||||
const SelectMarkCollection = dynamic(() => import('./components/SelectMarkCollection'));
|
||||
@@ -1014,10 +1013,6 @@ const ChatBox = ({
|
||||
onReadUserDislike: onReadUserDislike(item)
|
||||
}}
|
||||
>
|
||||
<ResponseTags
|
||||
showTags={index !== chatRecords.length - 1 || !isChatting}
|
||||
historyItem={item}
|
||||
/>
|
||||
{/* custom feedback */}
|
||||
{item.customFeedbacks && item.customFeedbacks.length > 0 && (
|
||||
<Box>
|
||||
@@ -1072,7 +1067,6 @@ const ChatBox = ({
|
||||
chatType,
|
||||
delOneMessage,
|
||||
externalVariableList?.length,
|
||||
isChatting,
|
||||
onAddUserDislike,
|
||||
onAddUserLike,
|
||||
onCloseCustomFeedback,
|
||||
|
||||
@@ -30,7 +30,7 @@ import { eventBus, EventNameEnum } from '@/web/common/utils/eventbus';
|
||||
import { SelectOptionsComponent, FormInputComponent } from './Interactive/InteractiveComponents';
|
||||
import { extractDeepestInteractive } from '@fastgpt/global/core/workflow/runtime/utils';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
||||
import { type OnOpenCiteModalProps } from '@/web/core/chat/context/chatItemContext';
|
||||
import { ChatBoxContext } from '../ChatContainer/ChatBox/Provider';
|
||||
import { useCreation } from 'ahooks';
|
||||
|
||||
@@ -90,11 +90,13 @@ const RenderResoningContent = React.memo(function RenderResoningContent({
|
||||
const RenderText = React.memo(function RenderText({
|
||||
showAnimation,
|
||||
text,
|
||||
chatItemDataId
|
||||
chatItemDataId,
|
||||
onOpenCiteModal
|
||||
}: {
|
||||
showAnimation: boolean;
|
||||
text: string;
|
||||
chatItemDataId: string;
|
||||
onOpenCiteModal?: (e?: OnOpenCiteModalProps) => void;
|
||||
}) {
|
||||
const appId = useContextSelector(ChatBoxContext, (v) => v.appId);
|
||||
const chatId = useContextSelector(ChatBoxContext, (v) => v.chatId);
|
||||
@@ -111,7 +113,14 @@ const RenderText = React.memo(function RenderText({
|
||||
return { appId, chatId, chatItemDataId, ...outLinkAuthData };
|
||||
}, [appId, chatId, chatItemDataId, outLinkAuthData]);
|
||||
|
||||
return <Markdown source={source} showAnimation={showAnimation} chatAuthData={chatAuthData} />;
|
||||
return (
|
||||
<Markdown
|
||||
source={source}
|
||||
showAnimation={showAnimation}
|
||||
chatAuthData={chatAuthData}
|
||||
onOpenCiteModal={onOpenCiteModal}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const RenderTool = React.memo(
|
||||
@@ -240,12 +249,14 @@ const AIResponseBox = ({
|
||||
chatItemDataId,
|
||||
value,
|
||||
isLastResponseValue,
|
||||
isChatting
|
||||
isChatting,
|
||||
onOpenCiteModal
|
||||
}: {
|
||||
chatItemDataId: string;
|
||||
value: UserChatItemValueItemType | AIChatItemValueItemType;
|
||||
isLastResponseValue: boolean;
|
||||
isChatting: boolean;
|
||||
onOpenCiteModal?: (e?: OnOpenCiteModalProps) => void;
|
||||
}) => {
|
||||
if (value.type === ChatItemValueTypeEnum.text && value.text) {
|
||||
return (
|
||||
@@ -253,6 +264,7 @@ const AIResponseBox = ({
|
||||
chatItemDataId={chatItemDataId}
|
||||
showAnimation={isChatting && isLastResponseValue}
|
||||
text={value.text.content}
|
||||
onOpenCiteModal={onOpenCiteModal}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user