mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-15 23:55:36 +00:00
add external variable debug (#4204)
* add external variable debug * fix ui * plugin variables
This commit is contained in:
@@ -430,6 +430,8 @@
|
|||||||
"core.chat.Start Chat": "Start Chat",
|
"core.chat.Start Chat": "Start Chat",
|
||||||
"core.chat.Type a message": "Enter a Question, Press [Enter] to Send / Press [Ctrl(Alt/Shift) + Enter] for New Line",
|
"core.chat.Type a message": "Enter a Question, Press [Enter] to Send / Press [Ctrl(Alt/Shift) + Enter] for New Line",
|
||||||
"core.chat.Unpin": "Unpin",
|
"core.chat.Unpin": "Unpin",
|
||||||
|
"core.chat.Variable_Visiable_in_test": "This variable is not visible in the login-free link",
|
||||||
|
"core.chat.Visiable_in_test": "Custom variables are not visible in login-free links",
|
||||||
"core.chat.You need to a chat app": "You Do Not Have an Available App",
|
"core.chat.You need to a chat app": "You Do Not Have an Available App",
|
||||||
"core.chat.error.Chat error": "Chat Error",
|
"core.chat.error.Chat error": "Chat Error",
|
||||||
"core.chat.error.Messages empty": "API Content is Empty, Possibly Due to Text Being Too Long",
|
"core.chat.error.Messages empty": "API Content is Empty, Possibly Due to Text Being Too Long",
|
||||||
|
@@ -433,6 +433,8 @@
|
|||||||
"core.chat.Start Chat": "开始对话",
|
"core.chat.Start Chat": "开始对话",
|
||||||
"core.chat.Type a message": "输入问题,发送 [Enter]/换行 [Ctrl(Alt/Shift) + Enter]",
|
"core.chat.Type a message": "输入问题,发送 [Enter]/换行 [Ctrl(Alt/Shift) + Enter]",
|
||||||
"core.chat.Unpin": "取消置顶",
|
"core.chat.Unpin": "取消置顶",
|
||||||
|
"core.chat.Variable_Visiable_in_test": "该变量在免登录链接中不可见",
|
||||||
|
"core.chat.Visiable_in_test": "自定义变量在免登录链接中不可见",
|
||||||
"core.chat.You need to a chat app": "你没有可用的应用",
|
"core.chat.You need to a chat app": "你没有可用的应用",
|
||||||
"core.chat.error.Chat error": "对话出现异常",
|
"core.chat.error.Chat error": "对话出现异常",
|
||||||
"core.chat.error.Messages empty": "接口内容为空,可能文本超长了~",
|
"core.chat.error.Messages empty": "接口内容为空,可能文本超长了~",
|
||||||
|
@@ -429,6 +429,8 @@
|
|||||||
"core.chat.Start Chat": "開始對話",
|
"core.chat.Start Chat": "開始對話",
|
||||||
"core.chat.Type a message": "輸入問題,按 [Enter] 傳送 / 按 [Ctrl(Alt/Shift) + Enter] 換行",
|
"core.chat.Type a message": "輸入問題,按 [Enter] 傳送 / 按 [Ctrl(Alt/Shift) + Enter] 換行",
|
||||||
"core.chat.Unpin": "取消釘選",
|
"core.chat.Unpin": "取消釘選",
|
||||||
|
"core.chat.Variable_Visiable_in_test": "該變量在免登錄鏈接中不可見",
|
||||||
|
"core.chat.Visiable_in_test": "自定義變量在免登錄鏈接中不可見",
|
||||||
"core.chat.You need to a chat app": "您沒有可用的應用程式",
|
"core.chat.You need to a chat app": "您沒有可用的應用程式",
|
||||||
"core.chat.error.Chat error": "對話發生錯誤",
|
"core.chat.error.Chat error": "對話發生錯誤",
|
||||||
"core.chat.error.Messages empty": "API 內容為空,可能是文字過長",
|
"core.chat.error.Messages empty": "API 內容為空,可能是文字過長",
|
||||||
|
@@ -1,20 +1,26 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useMemo } from 'react';
|
||||||
import { Controller, UseFormReturn } from 'react-hook-form';
|
import { Controller, UseFormReturn } from 'react-hook-form';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { Box, Button, Card, Textarea } from '@chakra-ui/react';
|
import { Box, Button, Card, Flex, Switch, Textarea } from '@chakra-ui/react';
|
||||||
import ChatAvatar from './ChatAvatar';
|
import ChatAvatar from './ChatAvatar';
|
||||||
import { MessageCardStyle } from '../constants';
|
import { MessageCardStyle } from '../constants';
|
||||||
import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
|
import {
|
||||||
|
VariableInputEnum,
|
||||||
|
WorkflowIOValueTypeEnum
|
||||||
|
} from '@fastgpt/global/core/workflow/constants';
|
||||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import { ChatBoxInputFormType } from '../type.d';
|
import { ChatBoxInputFormType } from '../type.d';
|
||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import { ChatBoxContext } from '../Provider';
|
|
||||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||||
import { VariableItemType } from '@fastgpt/global/core/app/type';
|
import { VariableItemType } from '@fastgpt/global/core/app/type';
|
||||||
import MyTextarea from '@/components/common/Textarea/MyTextarea';
|
import MyTextarea from '@/components/common/Textarea/MyTextarea';
|
||||||
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput';
|
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput';
|
||||||
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
||||||
|
import { ChatBoxContext } from '../Provider';
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
|
const JsonEditor = dynamic(() => import('@fastgpt/web/components/common/Textarea/JsonEditor'));
|
||||||
|
|
||||||
export const VariableInputItem = ({
|
export const VariableInputItem = ({
|
||||||
item,
|
item,
|
||||||
@@ -108,23 +114,118 @@ export const VariableInputItem = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ExternalVariableInputItem = ({
|
||||||
|
item,
|
||||||
|
variablesForm,
|
||||||
|
showTag = false
|
||||||
|
}: {
|
||||||
|
item: VariableItemType;
|
||||||
|
variablesForm: UseFormReturn<any>;
|
||||||
|
showTag?: boolean;
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { register, control } = variablesForm;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box key={item.id} mb={4} pl={1}>
|
||||||
|
<Box
|
||||||
|
as={'label'}
|
||||||
|
display={'flex'}
|
||||||
|
position={'relative'}
|
||||||
|
mb={1}
|
||||||
|
alignItems={'center'}
|
||||||
|
w={'full'}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
{item.required && (
|
||||||
|
<Box position={'absolute'} top={'-2px'} left={'-8px'} color={'red.500'}>
|
||||||
|
*
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
{item.description && <QuestionTip ml={1} label={item.description} />}
|
||||||
|
{showTag && (
|
||||||
|
<Flex
|
||||||
|
color={'primary.600'}
|
||||||
|
bg={'primary.100'}
|
||||||
|
px={2}
|
||||||
|
py={1}
|
||||||
|
gap={1}
|
||||||
|
ml={2}
|
||||||
|
fontSize={'mini'}
|
||||||
|
rounded={'sm'}
|
||||||
|
>
|
||||||
|
<MyIcon name={'common/info'} color={'primary.600'} w={4} />
|
||||||
|
{t('common:core.chat.Variable_Visiable_in_test')}
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`variables.${item.key}`}
|
||||||
|
rules={{
|
||||||
|
required: item.required,
|
||||||
|
validate: (value) => {
|
||||||
|
if (item.valueType === WorkflowIOValueTypeEnum.boolean) {
|
||||||
|
return value !== undefined;
|
||||||
|
}
|
||||||
|
return !!value;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
render={({ field: { onChange, value } }) => {
|
||||||
|
if (item.valueType === WorkflowIOValueTypeEnum.string) {
|
||||||
|
return (
|
||||||
|
<MyTextarea
|
||||||
|
autoHeight
|
||||||
|
minH={40}
|
||||||
|
maxH={160}
|
||||||
|
bg={'myGray.50'}
|
||||||
|
{...register(`variables.${item.key}`, {
|
||||||
|
required: item.required
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (item.valueType === WorkflowIOValueTypeEnum.number) {
|
||||||
|
return <MyNumberInput step={1} bg={'myGray.50'} value={value} onChange={onChange} />;
|
||||||
|
}
|
||||||
|
if (item.valueType === WorkflowIOValueTypeEnum.boolean) {
|
||||||
|
return <Switch isChecked={value} onChange={onChange} />;
|
||||||
|
}
|
||||||
|
return <JsonEditor bg={'myGray.50'} resize value={value} onChange={onChange} />;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const VariableInput = ({
|
const VariableInput = ({
|
||||||
chatForm,
|
chatForm,
|
||||||
chatStarted
|
chatStarted,
|
||||||
|
showExternalVariables = false
|
||||||
}: {
|
}: {
|
||||||
chatStarted: boolean;
|
|
||||||
chatForm: UseFormReturn<ChatBoxInputFormType>;
|
chatForm: UseFormReturn<ChatBoxInputFormType>;
|
||||||
|
chatStarted: boolean;
|
||||||
|
showExternalVariables?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const appAvatar = useContextSelector(ChatItemContext, (v) => v.chatBoxData?.app?.avatar);
|
const appAvatar = useContextSelector(ChatItemContext, (v) => v.chatBoxData?.app?.avatar);
|
||||||
const variablesForm = useContextSelector(ChatItemContext, (v) => v.variablesForm);
|
const variablesForm = useContextSelector(ChatItemContext, (v) => v.variablesForm);
|
||||||
const variableList = useContextSelector(ChatBoxContext, (v) => v.variableList);
|
const variableList = useContextSelector(ChatBoxContext, (v) => v.variableList);
|
||||||
|
const allVariableList = useContextSelector(ChatBoxContext, (v) => v.allVariableList);
|
||||||
|
|
||||||
|
const externalVariableList = useMemo(
|
||||||
|
() =>
|
||||||
|
allVariableList.filter((item) =>
|
||||||
|
showExternalVariables ? item.type === VariableInputEnum.custom : false
|
||||||
|
),
|
||||||
|
[allVariableList, showExternalVariables]
|
||||||
|
);
|
||||||
|
|
||||||
const { getValues, setValue, handleSubmit: handleSubmitChat } = variablesForm;
|
const { getValues, setValue, handleSubmit: handleSubmitChat } = variablesForm;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
variableList.forEach((item) => {
|
allVariableList.forEach((item) => {
|
||||||
const val = getValues(`variables.${item.key}`);
|
const val = getValues(`variables.${item.key}`);
|
||||||
if (item.defaultValue !== undefined && (val === undefined || val === null || val === '')) {
|
if (item.defaultValue !== undefined && (val === undefined || val === null || val === '')) {
|
||||||
setValue(`variables.${item.key}`, item.defaultValue);
|
setValue(`variables.${item.key}`, item.defaultValue);
|
||||||
@@ -135,6 +236,51 @@ const VariableInput = ({
|
|||||||
return (
|
return (
|
||||||
<Box py={3}>
|
<Box py={3}>
|
||||||
<ChatAvatar src={appAvatar} type={'AI'} />
|
<ChatAvatar src={appAvatar} type={'AI'} />
|
||||||
|
{externalVariableList.length > 0 && (
|
||||||
|
<Box textAlign={'left'}>
|
||||||
|
<Card
|
||||||
|
order={2}
|
||||||
|
mt={2}
|
||||||
|
w={'400px'}
|
||||||
|
{...MessageCardStyle}
|
||||||
|
bg={'white'}
|
||||||
|
boxShadow={'0 0 8px rgba(0,0,0,0.15)'}
|
||||||
|
>
|
||||||
|
<Flex
|
||||||
|
color={'primary.600'}
|
||||||
|
bg={'primary.100'}
|
||||||
|
mb={3}
|
||||||
|
px={3}
|
||||||
|
py={1.5}
|
||||||
|
gap={1}
|
||||||
|
fontSize={'mini'}
|
||||||
|
rounded={'sm'}
|
||||||
|
>
|
||||||
|
<MyIcon name={'common/info'} color={'primary.600'} w={4} />
|
||||||
|
{t('common:core.chat.Visiable_in_test')}
|
||||||
|
</Flex>
|
||||||
|
{externalVariableList.map((item) => (
|
||||||
|
<ExternalVariableInputItem key={item.id} item={item} variablesForm={variablesForm} />
|
||||||
|
))}
|
||||||
|
{variableList.length === 0 && !chatStarted && (
|
||||||
|
<Box>
|
||||||
|
<Button
|
||||||
|
leftIcon={<MyIcon name={'core/chat/chatFill'} w={'16px'} />}
|
||||||
|
size={'sm'}
|
||||||
|
maxW={'100px'}
|
||||||
|
onClick={handleSubmitChat(() => {
|
||||||
|
chatForm.setValue('chatStarted', true);
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{t('common:core.chat.Start Chat')}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{variableList.length > 0 && (
|
||||||
<Box textAlign={'left'}>
|
<Box textAlign={'left'}>
|
||||||
<Card
|
<Card
|
||||||
order={2}
|
order={2}
|
||||||
@@ -163,6 +309,7 @@ const VariableInput = ({
|
|||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -0,0 +1,98 @@
|
|||||||
|
import { Box, Button, Flex } from '@chakra-ui/react';
|
||||||
|
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
|
import { useContextSelector } from 'use-context-selector';
|
||||||
|
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
||||||
|
import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { ExternalVariableInputItem, VariableInputItem } from './VariableInput';
|
||||||
|
import MyDivider from '@fastgpt/web/components/common/MyDivider';
|
||||||
|
|
||||||
|
const VariablePopover = ({
|
||||||
|
showExternalVariables = false
|
||||||
|
}: {
|
||||||
|
showExternalVariables?: boolean;
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const variablesForm = useContextSelector(ChatItemContext, (v) => v.variablesForm);
|
||||||
|
const variables = useContextSelector(
|
||||||
|
ChatItemContext,
|
||||||
|
(v) => v.chatBoxData?.app?.chatConfig?.variables ?? []
|
||||||
|
);
|
||||||
|
const variableList = variables.filter((item) => item.type !== VariableInputEnum.custom);
|
||||||
|
const externalVariableList = variables.filter((item) =>
|
||||||
|
showExternalVariables ? item.type === VariableInputEnum.custom : false
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasExternalVariable = externalVariableList.length > 0;
|
||||||
|
const hasVariable = variableList.length > 0;
|
||||||
|
|
||||||
|
const { getValues, setValue } = variablesForm;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
variables.forEach((item) => {
|
||||||
|
const val = getValues(`variables.${item.key}`);
|
||||||
|
if (item.defaultValue !== undefined && (val === undefined || val === null || val === '')) {
|
||||||
|
setValue(`variables.${item.key}`, item.defaultValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [variables]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MyPopover
|
||||||
|
placement="bottom"
|
||||||
|
trigger={'click'}
|
||||||
|
closeOnBlur={true}
|
||||||
|
Trigger={
|
||||||
|
<Button variant={'whiteBase'} leftIcon={<MyIcon name={'edit'} w={4} />}>
|
||||||
|
{t('common:core.module.Variable')}
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{({ onClose }) => (
|
||||||
|
<Box p={4}>
|
||||||
|
{hasExternalVariable && (
|
||||||
|
<Box textAlign={'left'}>
|
||||||
|
<Flex
|
||||||
|
color={'primary.600'}
|
||||||
|
bg={'primary.100'}
|
||||||
|
mb={3}
|
||||||
|
px={3}
|
||||||
|
py={1.5}
|
||||||
|
gap={1}
|
||||||
|
fontSize={'mini'}
|
||||||
|
rounded={'sm'}
|
||||||
|
>
|
||||||
|
<MyIcon name={'common/info'} color={'primary.600'} w={4} />
|
||||||
|
{t('common:core.chat.Visiable_in_test')}
|
||||||
|
</Flex>
|
||||||
|
{externalVariableList.map((item) => (
|
||||||
|
<ExternalVariableInputItem
|
||||||
|
key={item.id}
|
||||||
|
item={item}
|
||||||
|
variablesForm={variablesForm}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
{hasExternalVariable && hasVariable && <MyDivider h={'1px'} />}
|
||||||
|
{hasVariable && (
|
||||||
|
<Box textAlign={'left'}>
|
||||||
|
{variableList.map((item) => (
|
||||||
|
<VariableInputItem key={item.id} item={item} variablesForm={variablesForm} />
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<Flex w={'full'} justifyContent={'flex-end'}>
|
||||||
|
<Button size={'sm'} onClick={onClose}>
|
||||||
|
{t('common:common.Confirm')}
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</MyPopover>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default VariablePopover;
|
@@ -65,6 +65,7 @@ import { ChatRecordContext } from '@/web/core/chat/context/chatRecordContext';
|
|||||||
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
||||||
import TimeBox from './components/TimeBox';
|
import TimeBox from './components/TimeBox';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
|
import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
|
||||||
|
|
||||||
const ResponseTags = dynamic(() => import('./components/ResponseTags'));
|
const ResponseTags = dynamic(() => import('./components/ResponseTags'));
|
||||||
const FeedbackModal = dynamic(() => import('./components/FeedbackModal'));
|
const FeedbackModal = dynamic(() => import('./components/FeedbackModal'));
|
||||||
@@ -103,7 +104,8 @@ const ChatBox = ({
|
|||||||
showVoiceIcon = true,
|
showVoiceIcon = true,
|
||||||
showEmptyIntro = false,
|
showEmptyIntro = false,
|
||||||
active = true,
|
active = true,
|
||||||
onStartChat
|
onStartChat,
|
||||||
|
chatType
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const ScrollContainerRef = useRef<HTMLDivElement>(null);
|
const ScrollContainerRef = useRef<HTMLDivElement>(null);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -129,6 +131,8 @@ const ChatBox = ({
|
|||||||
const chatBoxData = useContextSelector(ChatItemContext, (v) => v.chatBoxData);
|
const chatBoxData = useContextSelector(ChatItemContext, (v) => v.chatBoxData);
|
||||||
const ChatBoxRef = useContextSelector(ChatItemContext, (v) => v.ChatBoxRef);
|
const ChatBoxRef = useContextSelector(ChatItemContext, (v) => v.ChatBoxRef);
|
||||||
const variablesForm = useContextSelector(ChatItemContext, (v) => v.variablesForm);
|
const variablesForm = useContextSelector(ChatItemContext, (v) => v.variablesForm);
|
||||||
|
const setIsVariableVisible = useContextSelector(ChatItemContext, (v) => v.setIsVariableVisible);
|
||||||
|
|
||||||
const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords);
|
const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords);
|
||||||
const setChatRecords = useContextSelector(ChatRecordContext, (v) => v.setChatRecords);
|
const setChatRecords = useContextSelector(ChatRecordContext, (v) => v.setChatRecords);
|
||||||
const isChatRecordsLoaded = useContextSelector(ChatRecordContext, (v) => v.isChatRecordsLoaded);
|
const isChatRecordsLoaded = useContextSelector(ChatRecordContext, (v) => v.isChatRecordsLoaded);
|
||||||
@@ -150,6 +154,12 @@ const ChatBox = ({
|
|||||||
// Workflow running, there are user input or selection
|
// Workflow running, there are user input or selection
|
||||||
const isInteractive = useMemo(() => checkIsInteractiveByHistories(chatRecords), [chatRecords]);
|
const isInteractive = useMemo(() => checkIsInteractiveByHistories(chatRecords), [chatRecords]);
|
||||||
|
|
||||||
|
const externalVariableList = useMemo(() => {
|
||||||
|
if (chatType === 'chat') {
|
||||||
|
return allVariableList.filter((item) => item.type === VariableInputEnum.custom);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}, [allVariableList, chatType]);
|
||||||
// compute variable input is finish.
|
// compute variable input is finish.
|
||||||
const chatForm = useForm<ChatBoxInputFormType>({
|
const chatForm = useForm<ChatBoxInputFormType>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
@@ -162,7 +172,9 @@ const ChatBox = ({
|
|||||||
const chatStartedWatch = watch('chatStarted');
|
const chatStartedWatch = watch('chatStarted');
|
||||||
const chatStarted =
|
const chatStarted =
|
||||||
chatBoxData?.appId === appId &&
|
chatBoxData?.appId === appId &&
|
||||||
(chatStartedWatch || chatRecords.length > 0 || variableList.length === 0);
|
(chatStartedWatch ||
|
||||||
|
chatRecords.length > 0 ||
|
||||||
|
[...variableList, ...externalVariableList].length === 0);
|
||||||
|
|
||||||
// 滚动到底部
|
// 滚动到底部
|
||||||
const scrollToBottom = useMemoizedFn((behavior: 'smooth' | 'auto' = 'smooth', delay = 0) => {
|
const scrollToBottom = useMemoizedFn((behavior: 'smooth' | 'auto' = 'smooth', delay = 0) => {
|
||||||
@@ -891,6 +903,33 @@ const ChatBox = ({
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Visibility check
|
||||||
|
useEffect(() => {
|
||||||
|
const checkVariableVisibility = () => {
|
||||||
|
if (!ScrollContainerRef.current) return;
|
||||||
|
const container = ScrollContainerRef.current;
|
||||||
|
const variableInput = container.querySelector('#variable-input');
|
||||||
|
if (!variableInput) return;
|
||||||
|
|
||||||
|
const containerRect = container.getBoundingClientRect();
|
||||||
|
const elementRect = variableInput.getBoundingClientRect();
|
||||||
|
|
||||||
|
setIsVariableVisible(
|
||||||
|
elementRect.bottom > containerRect.top && elementRect.top < containerRect.bottom
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const container = ScrollContainerRef.current;
|
||||||
|
if (container) {
|
||||||
|
container.addEventListener('scroll', checkVariableVisibility);
|
||||||
|
checkVariableVisibility();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
container.removeEventListener('scroll', checkVariableVisibility);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [setIsVariableVisible]);
|
||||||
|
|
||||||
const RenderRecords = useMemo(() => {
|
const RenderRecords = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
<ScrollData
|
<ScrollData
|
||||||
@@ -906,8 +945,14 @@ const ChatBox = ({
|
|||||||
{showEmpty && <Empty />}
|
{showEmpty && <Empty />}
|
||||||
{!!welcomeText && <WelcomeBox welcomeText={welcomeText} />}
|
{!!welcomeText && <WelcomeBox welcomeText={welcomeText} />}
|
||||||
{/* variable input */}
|
{/* variable input */}
|
||||||
{!!variableList?.length && (
|
{(!!variableList?.length || !!externalVariableList?.length) && (
|
||||||
<VariableInput chatStarted={chatStarted} chatForm={chatForm} />
|
<Box id="variable-input">
|
||||||
|
<VariableInput
|
||||||
|
chatStarted={chatStarted}
|
||||||
|
chatForm={chatForm}
|
||||||
|
showExternalVariables={chatType === 'chat'}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
)}
|
)}
|
||||||
{/* chat history */}
|
{/* chat history */}
|
||||||
<Box id={'history'}>
|
<Box id={'history'}>
|
||||||
@@ -1006,7 +1051,9 @@ const ChatBox = ({
|
|||||||
chatForm,
|
chatForm,
|
||||||
chatRecords,
|
chatRecords,
|
||||||
chatStarted,
|
chatStarted,
|
||||||
|
chatType,
|
||||||
delOneMessage,
|
delOneMessage,
|
||||||
|
externalVariableList?.length,
|
||||||
isChatting,
|
isChatting,
|
||||||
onAddUserDislike,
|
onAddUserDislike,
|
||||||
onAddUserLike,
|
onAddUserLike,
|
||||||
|
@@ -18,6 +18,7 @@ import { ChatBoxInputFormType } from '../../ChatBox/type';
|
|||||||
import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io';
|
import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io';
|
||||||
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
||||||
import { ChatRecordContext } from '@/web/core/chat/context/chatRecordContext';
|
import { ChatRecordContext } from '@/web/core/chat/context/chatRecordContext';
|
||||||
|
import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||||
|
|
||||||
const RenderInput = () => {
|
const RenderInput = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -213,7 +214,14 @@ const RenderInput = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
{/* Filed */}
|
{/* Filed */}
|
||||||
{formatPluginInputs.map((input) => {
|
{formatPluginInputs
|
||||||
|
.filter((input) => {
|
||||||
|
if (outLinkAuthData && Object.keys(outLinkAuthData).length > 0) {
|
||||||
|
return input.renderTypeList[0] !== FlowNodeInputTypeEnum.customVariable;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map((input) => {
|
||||||
return (
|
return (
|
||||||
<Controller
|
<Controller
|
||||||
key={`variables.${input.key}`}
|
key={`variables.${input.key}`}
|
||||||
|
@@ -157,9 +157,6 @@ const RenderPluginInput = ({
|
|||||||
const { llmModelList } = useSystemStore();
|
const { llmModelList } = useSystemStore();
|
||||||
|
|
||||||
const render = (() => {
|
const render = (() => {
|
||||||
if (inputType === FlowNodeInputTypeEnum.customVariable) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (inputType === FlowNodeInputTypeEnum.select && input.list) {
|
if (inputType === FlowNodeInputTypeEnum.select && input.list) {
|
||||||
return (
|
return (
|
||||||
<MySelect list={input.list} value={value} onChange={onChange} isDisabled={isDisabled} />
|
<MySelect list={input.list} value={value} onChange={onChange} isDisabled={isDisabled} />
|
||||||
@@ -246,6 +243,21 @@ const RenderPluginInput = ({
|
|||||||
<FormLabel fontWeight={'500'}>{t(input.label as any)}</FormLabel>
|
<FormLabel fontWeight={'500'}>{t(input.label as any)}</FormLabel>
|
||||||
</Box>
|
</Box>
|
||||||
{input.description && <QuestionTip ml={2} label={t(input.description as any)} />}
|
{input.description && <QuestionTip ml={2} label={t(input.description as any)} />}
|
||||||
|
{inputType === FlowNodeInputTypeEnum.customVariable && (
|
||||||
|
<Flex
|
||||||
|
color={'primary.600'}
|
||||||
|
bg={'primary.100'}
|
||||||
|
px={2}
|
||||||
|
py={1}
|
||||||
|
gap={1}
|
||||||
|
ml={2}
|
||||||
|
fontSize={'mini'}
|
||||||
|
rounded={'sm'}
|
||||||
|
>
|
||||||
|
<MyIcon name={'common/info'} color={'primary.600'} w={4} />
|
||||||
|
{t('common:core.chat.Variable_Visiable_in_test')}
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { Box, Flex, IconButton } from '@chakra-ui/react';
|
import { Box, Button, Flex, IconButton } from '@chakra-ui/react';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import React, { useEffect, useMemo } from 'react';
|
import React, { useEffect, useMemo } from 'react';
|
||||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||||
@@ -10,12 +10,14 @@ import { form2AppWorkflow } from '@/web/core/app/utils';
|
|||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import { AppContext } from '../context';
|
import { AppContext } from '../context';
|
||||||
import { useChatTest } from '../useChatTest';
|
import { useChatTest } from '../useChatTest';
|
||||||
|
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
||||||
import ChatItemContextProvider, { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
import ChatItemContextProvider, { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
||||||
import ChatRecordContextProvider from '@/web/core/chat/context/chatRecordContext';
|
import ChatRecordContextProvider from '@/web/core/chat/context/chatRecordContext';
|
||||||
import { useChatStore } from '@/web/core/chat/context/useChatStore';
|
import { useChatStore } from '@/web/core/chat/context/useChatStore';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import { cardStyles } from '../constants';
|
import { cardStyles } from '../constants';
|
||||||
import ChatQuoteList from '@/pageComponents/chat/ChatQuoteList';
|
import ChatQuoteList from '@/pageComponents/chat/ChatQuoteList';
|
||||||
|
import VariablePopover from '@/components/core/chat/ChatContainer/ChatBox/components/VariablePopover';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
appForm: AppSimpleEditFormType;
|
appForm: AppSimpleEditFormType;
|
||||||
@@ -27,6 +29,8 @@ const ChatTest = ({ appForm, setRenderEdit }: Props) => {
|
|||||||
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
||||||
const quoteData = useContextSelector(ChatItemContext, (v) => v.quoteData);
|
const quoteData = useContextSelector(ChatItemContext, (v) => v.quoteData);
|
||||||
const setQuoteData = useContextSelector(ChatItemContext, (v) => v.setQuoteData);
|
const setQuoteData = useContextSelector(ChatItemContext, (v) => v.setQuoteData);
|
||||||
|
// form2AppWorkflow dependent allDatasets
|
||||||
|
const isVariableVisible = useContextSelector(ChatItemContext, (v) => v.isVariableVisible);
|
||||||
|
|
||||||
const [workflowData, setWorkflowData] = useSafeState({
|
const [workflowData, setWorkflowData] = useSafeState({
|
||||||
nodes: appDetail.modules || [],
|
nodes: appDetail.modules || [],
|
||||||
@@ -62,10 +66,12 @@ const ChatTest = ({ appForm, setRenderEdit }: Props) => {
|
|||||||
{...cardStyles}
|
{...cardStyles}
|
||||||
boxShadow={'3'}
|
boxShadow={'3'}
|
||||||
>
|
>
|
||||||
<Flex px={[2, 5]}>
|
<Flex px={[2, 5]} pb={2}>
|
||||||
<Box fontSize={['md', 'lg']} fontWeight={'bold'} flex={1} color={'myGray.900'}>
|
<Box fontSize={['md', 'lg']} fontWeight={'bold'} color={'myGray.900'} mr={3}>
|
||||||
{t('app:chat_debug')}
|
{t('app:chat_debug')}
|
||||||
</Box>
|
</Box>
|
||||||
|
{!isVariableVisible && <VariablePopover showExternalVariables={true} />}
|
||||||
|
<Box flex={1} />
|
||||||
<MyTooltip label={t('common:core.chat.Restart')}>
|
<MyTooltip label={t('common:core.chat.Restart')}>
|
||||||
<IconButton
|
<IconButton
|
||||||
className="chat"
|
className="chat"
|
||||||
|
@@ -21,6 +21,7 @@ import ChatRecordContextProvider, {
|
|||||||
import { useChatStore } from '@/web/core/chat/context/useChatStore';
|
import { useChatStore } from '@/web/core/chat/context/useChatStore';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import ChatQuoteList from '@/pageComponents/chat/ChatQuoteList';
|
import ChatQuoteList from '@/pageComponents/chat/ChatQuoteList';
|
||||||
|
import VariablePopover from '@/components/core/chat/ChatContainer/ChatBox/components/VariablePopover';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@@ -45,6 +46,7 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
|
|||||||
const quoteData = useContextSelector(ChatItemContext, (v) => v.quoteData);
|
const quoteData = useContextSelector(ChatItemContext, (v) => v.quoteData);
|
||||||
const setQuoteData = useContextSelector(ChatItemContext, (v) => v.setQuoteData);
|
const setQuoteData = useContextSelector(ChatItemContext, (v) => v.setQuoteData);
|
||||||
|
|
||||||
|
const isVariableVisible = useContextSelector(ChatItemContext, (v) => v.isVariableVisible);
|
||||||
const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords);
|
const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -115,10 +117,12 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
|
|||||||
bg={'myGray.25'}
|
bg={'myGray.25'}
|
||||||
borderBottom={'1px solid #F4F4F7'}
|
borderBottom={'1px solid #F4F4F7'}
|
||||||
>
|
>
|
||||||
<Flex fontSize={'16px'} fontWeight={'bold'} flex={1} alignItems={'center'}>
|
<Flex fontSize={'16px'} fontWeight={'bold'} alignItems={'center'} mr={3}>
|
||||||
<MyIcon name={'common/paused'} w={'14px'} mr={2.5} />
|
<MyIcon name={'common/paused'} w={'14px'} mr={2.5} />
|
||||||
{t('common:core.chat.Run test')}
|
{t('common:core.chat.Run test')}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
{!isVariableVisible && <VariablePopover showExternalVariables={true} />}
|
||||||
|
<Box flex={1} />
|
||||||
<MyTooltip label={t('common:core.chat.Restart')}>
|
<MyTooltip label={t('common:core.chat.Restart')}>
|
||||||
<IconButton
|
<IconButton
|
||||||
className="chat"
|
className="chat"
|
||||||
|
@@ -31,7 +31,10 @@ import { WorkflowContext } from '../../context';
|
|||||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||||
import { AppContext } from '../../../context';
|
import { AppContext } from '../../../context';
|
||||||
import { VariableInputItem } from '@/components/core/chat/ChatContainer/ChatBox/components/VariableInput';
|
import {
|
||||||
|
ExternalVariableInputItem,
|
||||||
|
VariableInputItem
|
||||||
|
} from '@/components/core/chat/ChatContainer/ChatBox/components/VariableInput';
|
||||||
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
|
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
|
||||||
import MyTextarea from '@/components/common/Textarea/MyTextarea';
|
import MyTextarea from '@/components/common/Textarea/MyTextarea';
|
||||||
import { WorkflowNodeEdgeContext } from '../../context/workflowInitContext';
|
import { WorkflowNodeEdgeContext } from '../../context/workflowInitContext';
|
||||||
@@ -58,13 +61,17 @@ export const useDebug = () => {
|
|||||||
|
|
||||||
const appDetail = useContextSelector(AppContext, (v) => v.appDetail);
|
const appDetail = useContextSelector(AppContext, (v) => v.appDetail);
|
||||||
|
|
||||||
const filteredVar = useMemo(() => {
|
const { filteredVar, customVar, variables } = useMemo(() => {
|
||||||
const variables = appDetail.chatConfig?.variables;
|
const variables = appDetail.chatConfig?.variables || [];
|
||||||
return variables?.filter((item) => item.type !== VariableInputEnum.custom) || [];
|
return {
|
||||||
|
filteredVar: variables.filter((item) => item.type !== VariableInputEnum.custom) || [],
|
||||||
|
customVar: variables.filter((item) => item.type === VariableInputEnum.custom) || [],
|
||||||
|
variables
|
||||||
|
};
|
||||||
}, [appDetail.chatConfig?.variables]);
|
}, [appDetail.chatConfig?.variables]);
|
||||||
|
|
||||||
const [defaultGlobalVariables, setDefaultGlobalVariables] = useState<Record<string, any>>(
|
const [defaultGlobalVariables, setDefaultGlobalVariables] = useState<Record<string, any>>(
|
||||||
filteredVar.reduce(
|
variables.reduce(
|
||||||
(acc, item) => {
|
(acc, item) => {
|
||||||
acc[item.key] = item.defaultValue;
|
acc[item.key] = item.defaultValue;
|
||||||
return acc;
|
return acc;
|
||||||
@@ -241,7 +248,7 @@ export const useDebug = () => {
|
|||||||
px={0}
|
px={0}
|
||||||
>
|
>
|
||||||
<Box flex={'1 0 0'} overflow={'auto'} px={6}>
|
<Box flex={'1 0 0'} overflow={'auto'} px={6}>
|
||||||
{filteredVar.length > 0 && (
|
{variables.length > 0 && (
|
||||||
<LightRowTabs<TabEnum>
|
<LightRowTabs<TabEnum>
|
||||||
gap={3}
|
gap={3}
|
||||||
ml={-2}
|
ml={-2}
|
||||||
@@ -256,6 +263,14 @@ export const useDebug = () => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Box display={currentTab === TabEnum.global ? 'block' : 'none'}>
|
<Box display={currentTab === TabEnum.global ? 'block' : 'none'}>
|
||||||
|
{customVar.map((item) => (
|
||||||
|
<ExternalVariableInputItem
|
||||||
|
key={item.id}
|
||||||
|
item={{ ...item, key: item.key }}
|
||||||
|
variablesForm={variablesForm}
|
||||||
|
showTag={true}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
{filteredVar.map((item) => (
|
{filteredVar.map((item) => (
|
||||||
<VariableInputItem
|
<VariableInputItem
|
||||||
key={item.id}
|
key={item.id}
|
||||||
@@ -354,13 +369,15 @@ export const useDebug = () => {
|
|||||||
</MyRightDrawer>
|
</MyRightDrawer>
|
||||||
);
|
);
|
||||||
}, [
|
}, [
|
||||||
defaultGlobalVariables,
|
|
||||||
filteredVar,
|
|
||||||
onStartNodeDebug,
|
|
||||||
runtimeEdges,
|
|
||||||
runtimeNodeId,
|
|
||||||
runtimeNodes,
|
runtimeNodes,
|
||||||
t
|
runtimeEdges,
|
||||||
|
defaultGlobalVariables,
|
||||||
|
t,
|
||||||
|
variables.length,
|
||||||
|
customVar,
|
||||||
|
filteredVar,
|
||||||
|
runtimeNodeId,
|
||||||
|
onStartNodeDebug
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@@ -297,8 +297,10 @@ const InputTypeConfig = ({
|
|||||||
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
|
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
|
||||||
{t('common:core.module.Default Value')}
|
{t('common:core.module.Default Value')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<Flex alignItems={'start'} flex={1} h={10}>
|
<Flex alignItems={'center'} flex={1} h={10}>
|
||||||
{inputType === FlowNodeInputTypeEnum.numberInput && (
|
{(inputType === FlowNodeInputTypeEnum.numberInput ||
|
||||||
|
(inputType === VariableInputEnum.custom &&
|
||||||
|
valueType === WorkflowIOValueTypeEnum.number)) && (
|
||||||
<MyNumberInput
|
<MyNumberInput
|
||||||
value={defaultValue}
|
value={defaultValue}
|
||||||
min={min}
|
min={min}
|
||||||
@@ -310,7 +312,8 @@ const InputTypeConfig = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{(inputType === FlowNodeInputTypeEnum.input ||
|
{(inputType === FlowNodeInputTypeEnum.input ||
|
||||||
inputType === VariableInputEnum.custom) && (
|
(inputType === VariableInputEnum.custom &&
|
||||||
|
valueType === WorkflowIOValueTypeEnum.string)) && (
|
||||||
<MyTextarea
|
<MyTextarea
|
||||||
{...register('defaultValue')}
|
{...register('defaultValue')}
|
||||||
bg={'myGray.50'}
|
bg={'myGray.50'}
|
||||||
@@ -319,7 +322,13 @@ const InputTypeConfig = ({
|
|||||||
maxH={100}
|
maxH={100}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{inputType === FlowNodeInputTypeEnum.JSONEditor && (
|
{(inputType === FlowNodeInputTypeEnum.JSONEditor ||
|
||||||
|
(inputType === VariableInputEnum.custom &&
|
||||||
|
![
|
||||||
|
WorkflowIOValueTypeEnum.number,
|
||||||
|
WorkflowIOValueTypeEnum.string,
|
||||||
|
WorkflowIOValueTypeEnum.boolean
|
||||||
|
].includes(valueType))) && (
|
||||||
<JsonEditor
|
<JsonEditor
|
||||||
bg={'myGray.50'}
|
bg={'myGray.50'}
|
||||||
resize
|
resize
|
||||||
@@ -330,7 +339,9 @@ const InputTypeConfig = ({
|
|||||||
defaultValue={defaultValue}
|
defaultValue={defaultValue}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{inputType === FlowNodeInputTypeEnum.switch && (
|
{(inputType === FlowNodeInputTypeEnum.switch ||
|
||||||
|
(inputType === VariableInputEnum.custom &&
|
||||||
|
valueType === WorkflowIOValueTypeEnum.boolean)) && (
|
||||||
<Switch {...register('defaultValue')} />
|
<Switch {...register('defaultValue')} />
|
||||||
)}
|
)}
|
||||||
{inputType === FlowNodeInputTypeEnum.select && (
|
{inputType === FlowNodeInputTypeEnum.select && (
|
||||||
|
@@ -140,7 +140,7 @@ export const useChatTest = ({
|
|||||||
appId={appId}
|
appId={appId}
|
||||||
chatId={chatId}
|
chatId={chatId}
|
||||||
showMarkIcon
|
showMarkIcon
|
||||||
chatType="chat"
|
chatType={'chat'}
|
||||||
onStartChat={startChat}
|
onStartChat={startChat}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
@@ -22,6 +22,7 @@ import {
|
|||||||
import { getMyApps } from '@/web/core/app/api';
|
import { getMyApps } from '@/web/core/app/api';
|
||||||
import SelectOneResource from '@/components/common/folder/SelectOneResource';
|
import SelectOneResource from '@/components/common/folder/SelectOneResource';
|
||||||
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
|
||||||
|
import VariablePopover from '@/components/core/chat/ChatContainer/ChatBox/components/VariablePopover';
|
||||||
|
|
||||||
const ChatHeader = ({
|
const ChatHeader = ({
|
||||||
history,
|
history,
|
||||||
@@ -38,7 +39,10 @@ const ChatHeader = ({
|
|||||||
const { isPc } = useSystem();
|
const { isPc } = useSystem();
|
||||||
|
|
||||||
const chatData = useContextSelector(ChatItemContext, (v) => v.chatBoxData);
|
const chatData = useContextSelector(ChatItemContext, (v) => v.chatBoxData);
|
||||||
|
const isVariableVisible = useContextSelector(ChatItemContext, (v) => v.isVariableVisible);
|
||||||
const isPlugin = chatData.app.type === AppTypeEnum.plugin;
|
const isPlugin = chatData.app.type === AppTypeEnum.plugin;
|
||||||
|
const router = useRouter();
|
||||||
|
const isChat = router.pathname === '/chat';
|
||||||
|
|
||||||
return isPc && isPlugin ? null : (
|
return isPc && isPlugin ? null : (
|
||||||
<Flex
|
<Flex
|
||||||
@@ -68,9 +72,13 @@ const ChatHeader = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<Flex gap={2} alignItems={'center'}>
|
||||||
|
{!isVariableVisible && <VariablePopover showExternalVariables={isChat} />}
|
||||||
|
|
||||||
{/* control */}
|
{/* control */}
|
||||||
{!isPlugin && <ToolMenu history={history} />}
|
{!isPlugin && <ToolMenu history={history} />}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -74,6 +74,8 @@ type ChatItemContextType = {
|
|||||||
|
|
||||||
quoteData?: QuoteDataType;
|
quoteData?: QuoteDataType;
|
||||||
setQuoteData: React.Dispatch<React.SetStateAction<QuoteDataType | undefined>>;
|
setQuoteData: React.Dispatch<React.SetStateAction<QuoteDataType | undefined>>;
|
||||||
|
isVariableVisible: boolean;
|
||||||
|
setIsVariableVisible: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
} & ContextProps;
|
} & ContextProps;
|
||||||
|
|
||||||
export const ChatItemContext = createContext<ChatItemContextType>({
|
export const ChatItemContext = createContext<ChatItemContextType>({
|
||||||
@@ -97,6 +99,10 @@ export const ChatItemContext = createContext<ChatItemContextType>({
|
|||||||
quoteData: undefined,
|
quoteData: undefined,
|
||||||
setQuoteData: function (value: React.SetStateAction<QuoteDataType | undefined>): void {
|
setQuoteData: function (value: React.SetStateAction<QuoteDataType | undefined>): void {
|
||||||
throw new Error('Function not implemented.');
|
throw new Error('Function not implemented.');
|
||||||
|
},
|
||||||
|
isVariableVisible: true,
|
||||||
|
setIsVariableVisible: function (value: React.SetStateAction<boolean>): void {
|
||||||
|
throw new Error('Function not implemented.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -116,6 +122,8 @@ const ChatItemContextProvider = ({
|
|||||||
const ChatBoxRef = useRef<ChatComponentRef>(null);
|
const ChatBoxRef = useRef<ChatComponentRef>(null);
|
||||||
const variablesForm = useForm<ChatBoxInputFormType>();
|
const variablesForm = useForm<ChatBoxInputFormType>();
|
||||||
const [quoteData, setQuoteData] = useState<QuoteDataType>();
|
const [quoteData, setQuoteData] = useState<QuoteDataType>();
|
||||||
|
const [isVariableVisible, setIsVariableVisible] = useState(true);
|
||||||
|
|
||||||
const [chatBoxData, setChatBoxData] = useState<ChatBoxDataType>({
|
const [chatBoxData, setChatBoxData] = useState<ChatBoxDataType>({
|
||||||
...defaultChatData
|
...defaultChatData
|
||||||
});
|
});
|
||||||
@@ -172,7 +180,9 @@ const ChatItemContextProvider = ({
|
|||||||
showNodeStatus,
|
showNodeStatus,
|
||||||
|
|
||||||
quoteData,
|
quoteData,
|
||||||
setQuoteData
|
setQuoteData,
|
||||||
|
isVariableVisible,
|
||||||
|
setIsVariableVisible
|
||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
chatBoxData,
|
chatBoxData,
|
||||||
@@ -187,7 +197,9 @@ const ChatItemContextProvider = ({
|
|||||||
// isShowFullText,
|
// isShowFullText,
|
||||||
showNodeStatus,
|
showNodeStatus,
|
||||||
quoteData,
|
quoteData,
|
||||||
setQuoteData
|
setQuoteData,
|
||||||
|
isVariableVisible,
|
||||||
|
setIsVariableVisible
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return <ChatItemContext.Provider value={contextValue}>{children}</ChatItemContext.Provider>;
|
return <ChatItemContext.Provider value={contextValue}>{children}</ChatItemContext.Provider>;
|
||||||
|
Reference in New Issue
Block a user