add external variable debug (#4204)

* add external variable debug

* fix ui

* plugin variables
This commit is contained in:
heheer
2025-03-19 11:57:30 +08:00
committed by archer
parent ec30d79286
commit d52700c645
15 changed files with 473 additions and 97 deletions

View File

@@ -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 React, { useEffect, useMemo } from 'react';
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 { AppContext } from '../context';
import { useChatTest } from '../useChatTest';
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
import ChatItemContextProvider, { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
import ChatRecordContextProvider from '@/web/core/chat/context/chatRecordContext';
import { useChatStore } from '@/web/core/chat/context/useChatStore';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { cardStyles } from '../constants';
import ChatQuoteList from '@/pageComponents/chat/ChatQuoteList';
import VariablePopover from '@/components/core/chat/ChatContainer/ChatBox/components/VariablePopover';
type Props = {
appForm: AppSimpleEditFormType;
@@ -27,6 +29,8 @@ const ChatTest = ({ appForm, setRenderEdit }: Props) => {
const { appDetail } = useContextSelector(AppContext, (v) => v);
const quoteData = useContextSelector(ChatItemContext, (v) => v.quoteData);
const setQuoteData = useContextSelector(ChatItemContext, (v) => v.setQuoteData);
// form2AppWorkflow dependent allDatasets
const isVariableVisible = useContextSelector(ChatItemContext, (v) => v.isVariableVisible);
const [workflowData, setWorkflowData] = useSafeState({
nodes: appDetail.modules || [],
@@ -62,10 +66,12 @@ const ChatTest = ({ appForm, setRenderEdit }: Props) => {
{...cardStyles}
boxShadow={'3'}
>
<Flex px={[2, 5]}>
<Box fontSize={['md', 'lg']} fontWeight={'bold'} flex={1} color={'myGray.900'}>
<Flex px={[2, 5]} pb={2}>
<Box fontSize={['md', 'lg']} fontWeight={'bold'} color={'myGray.900'} mr={3}>
{t('app:chat_debug')}
</Box>
{!isVariableVisible && <VariablePopover showExternalVariables={true} />}
<Box flex={1} />
<MyTooltip label={t('common:core.chat.Restart')}>
<IconButton
className="chat"

View File

@@ -21,6 +21,7 @@ import ChatRecordContextProvider, {
import { useChatStore } from '@/web/core/chat/context/useChatStore';
import MyBox from '@fastgpt/web/components/common/MyBox';
import ChatQuoteList from '@/pageComponents/chat/ChatQuoteList';
import VariablePopover from '@/components/core/chat/ChatContainer/ChatBox/components/VariablePopover';
type Props = {
isOpen: boolean;
@@ -45,6 +46,7 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
const quoteData = useContextSelector(ChatItemContext, (v) => v.quoteData);
const setQuoteData = useContextSelector(ChatItemContext, (v) => v.setQuoteData);
const isVariableVisible = useContextSelector(ChatItemContext, (v) => v.isVariableVisible);
const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords);
return (
@@ -115,10 +117,12 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
bg={'myGray.25'}
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} />
{t('common:core.chat.Run test')}
</Flex>
{!isVariableVisible && <VariablePopover showExternalVariables={true} />}
<Box flex={1} />
<MyTooltip label={t('common:core.chat.Restart')}>
<IconButton
className="chat"

View File

@@ -31,7 +31,10 @@ import { WorkflowContext } from '../../context';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
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 MyTextarea from '@/components/common/Textarea/MyTextarea';
import { WorkflowNodeEdgeContext } from '../../context/workflowInitContext';
@@ -58,13 +61,17 @@ export const useDebug = () => {
const appDetail = useContextSelector(AppContext, (v) => v.appDetail);
const filteredVar = useMemo(() => {
const variables = appDetail.chatConfig?.variables;
return variables?.filter((item) => item.type !== VariableInputEnum.custom) || [];
const { filteredVar, customVar, variables } = useMemo(() => {
const variables = appDetail.chatConfig?.variables || [];
return {
filteredVar: variables.filter((item) => item.type !== VariableInputEnum.custom) || [],
customVar: variables.filter((item) => item.type === VariableInputEnum.custom) || [],
variables
};
}, [appDetail.chatConfig?.variables]);
const [defaultGlobalVariables, setDefaultGlobalVariables] = useState<Record<string, any>>(
filteredVar.reduce(
variables.reduce(
(acc, item) => {
acc[item.key] = item.defaultValue;
return acc;
@@ -241,7 +248,7 @@ export const useDebug = () => {
px={0}
>
<Box flex={'1 0 0'} overflow={'auto'} px={6}>
{filteredVar.length > 0 && (
{variables.length > 0 && (
<LightRowTabs<TabEnum>
gap={3}
ml={-2}
@@ -256,6 +263,14 @@ export const useDebug = () => {
/>
)}
<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) => (
<VariableInputItem
key={item.id}
@@ -354,13 +369,15 @@ export const useDebug = () => {
</MyRightDrawer>
);
}, [
defaultGlobalVariables,
filteredVar,
onStartNodeDebug,
runtimeEdges,
runtimeNodeId,
runtimeNodes,
t
runtimeEdges,
defaultGlobalVariables,
t,
variables.length,
customVar,
filteredVar,
runtimeNodeId,
onStartNodeDebug
]);
return {

View File

@@ -297,8 +297,10 @@ const InputTypeConfig = ({
<FormLabel flex={'0 0 132px'} fontWeight={'medium'}>
{t('common:core.module.Default Value')}
</FormLabel>
<Flex alignItems={'start'} flex={1} h={10}>
{inputType === FlowNodeInputTypeEnum.numberInput && (
<Flex alignItems={'center'} flex={1} h={10}>
{(inputType === FlowNodeInputTypeEnum.numberInput ||
(inputType === VariableInputEnum.custom &&
valueType === WorkflowIOValueTypeEnum.number)) && (
<MyNumberInput
value={defaultValue}
min={min}
@@ -310,7 +312,8 @@ const InputTypeConfig = ({
/>
)}
{(inputType === FlowNodeInputTypeEnum.input ||
inputType === VariableInputEnum.custom) && (
(inputType === VariableInputEnum.custom &&
valueType === WorkflowIOValueTypeEnum.string)) && (
<MyTextarea
{...register('defaultValue')}
bg={'myGray.50'}
@@ -319,7 +322,13 @@ const InputTypeConfig = ({
maxH={100}
/>
)}
{inputType === FlowNodeInputTypeEnum.JSONEditor && (
{(inputType === FlowNodeInputTypeEnum.JSONEditor ||
(inputType === VariableInputEnum.custom &&
![
WorkflowIOValueTypeEnum.number,
WorkflowIOValueTypeEnum.string,
WorkflowIOValueTypeEnum.boolean
].includes(valueType))) && (
<JsonEditor
bg={'myGray.50'}
resize
@@ -330,7 +339,9 @@ const InputTypeConfig = ({
defaultValue={defaultValue}
/>
)}
{inputType === FlowNodeInputTypeEnum.switch && (
{(inputType === FlowNodeInputTypeEnum.switch ||
(inputType === VariableInputEnum.custom &&
valueType === WorkflowIOValueTypeEnum.boolean)) && (
<Switch {...register('defaultValue')} />
)}
{inputType === FlowNodeInputTypeEnum.select && (

View File

@@ -140,7 +140,7 @@ export const useChatTest = ({
appId={appId}
chatId={chatId}
showMarkIcon
chatType="chat"
chatType={'chat'}
onStartChat={startChat}
/>
)

View File

@@ -22,6 +22,7 @@ import {
import { getMyApps } from '@/web/core/app/api';
import SelectOneResource from '@/components/common/folder/SelectOneResource';
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
import VariablePopover from '@/components/core/chat/ChatContainer/ChatBox/components/VariablePopover';
const ChatHeader = ({
history,
@@ -38,7 +39,10 @@ const ChatHeader = ({
const { isPc } = useSystem();
const chatData = useContextSelector(ChatItemContext, (v) => v.chatBoxData);
const isVariableVisible = useContextSelector(ChatItemContext, (v) => v.isVariableVisible);
const isPlugin = chatData.app.type === AppTypeEnum.plugin;
const router = useRouter();
const isChat = router.pathname === '/chat';
return isPc && isPlugin ? null : (
<Flex
@@ -68,8 +72,12 @@ const ChatHeader = ({
/>
)}
{/* control */}
{!isPlugin && <ToolMenu history={history} />}
<Flex gap={2} alignItems={'center'}>
{!isVariableVisible && <VariablePopover showExternalVariables={isChat} />}
{/* control */}
{!isPlugin && <ToolMenu history={history} />}
</Flex>
</Flex>
);
};