mirror of
https://github.com/labring/FastGPT.git
synced 2025-08-02 20:58:12 +00:00
4.7.1-alpha2 (#1153)
Co-authored-by: UUUUnotfound <31206589+UUUUnotfound@users.noreply.github.com> Co-authored-by: Hexiao Zhang <731931282qq@gmail.com> Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
@@ -55,7 +55,7 @@ const SettingLLMModel = ({ llmModelType = LLMModelTypeEnum.all, defaultData, onC
|
||||
leftIcon={
|
||||
<Avatar
|
||||
borderRadius={'0'}
|
||||
src={selectedModel.avatar || HUGGING_FACE_ICON}
|
||||
src={selectedModel?.avatar || HUGGING_FACE_ICON}
|
||||
fallbackSrc={HUGGING_FACE_ICON}
|
||||
w={'18px'}
|
||||
/>
|
||||
|
@@ -5,7 +5,7 @@ import { Box, Button, Flex, ModalBody, useDisclosure, Image } from '@chakra-ui/r
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { TTSTypeEnum } from '@/constants/app';
|
||||
import type { AppTTSConfigType } from '@fastgpt/global/core/module/type.d';
|
||||
import type { AppTTSConfigType } from '@fastgpt/global/core/app/type.d';
|
||||
import { useAudioPlay } from '@/web/common/utils/voice';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
@@ -46,7 +46,9 @@ const TTSSelect = ({
|
||||
[formatValue, list, t]
|
||||
);
|
||||
|
||||
const { playAudio, cancelAudio, audioLoading, audioPlaying } = useAudioPlay({ ttsConfig: value });
|
||||
const { playAudioByText, cancelAudio, audioLoading, audioPlaying } = useAudioPlay({
|
||||
ttsConfig: value
|
||||
});
|
||||
|
||||
const onclickChange = useCallback(
|
||||
(e: string) => {
|
||||
@@ -137,9 +139,7 @@ const TTSSelect = ({
|
||||
color={'primary.600'}
|
||||
isLoading={audioLoading}
|
||||
leftIcon={<MyIcon name={'core/chat/stopSpeech'} w={'16px'} />}
|
||||
onClick={() => {
|
||||
cancelAudio();
|
||||
}}
|
||||
onClick={cancelAudio}
|
||||
>
|
||||
{t('core.chat.tts.Stop Speech')}
|
||||
</Button>
|
||||
@@ -149,7 +149,7 @@ const TTSSelect = ({
|
||||
isLoading={audioLoading}
|
||||
leftIcon={<MyIcon name={'core/app/headphones'} w={'16px'} />}
|
||||
onClick={() => {
|
||||
playAudio({
|
||||
playAudioByText({
|
||||
text: t('core.app.tts.Test Listen Text')
|
||||
});
|
||||
}}
|
@@ -26,7 +26,7 @@ import {
|
||||
} from '@chakra-ui/react';
|
||||
import { QuestionOutlineIcon, SmallAddIcon } from '@chakra-ui/icons';
|
||||
import { VariableInputEnum, variableMap } from '@fastgpt/global/core/module/constants';
|
||||
import type { VariableItemType } from '@fastgpt/global/core/module/type.d';
|
||||
import type { VariableItemType } from '@fastgpt/global/core/app/type.d';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useFieldArray } from 'react-hook-form';
|
116
projects/app/src/components/core/app/WhisperConfig.tsx
Normal file
116
projects/app/src/components/core/app/WhisperConfig.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import MyTooltip from '@/components/MyTooltip';
|
||||
import { Box, Button, Flex, ModalBody, useDisclosure, Switch } from '@chakra-ui/react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import type { AppWhisperConfigType } from '@fastgpt/global/core/app/type.d';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
|
||||
const WhisperConfig = ({
|
||||
isOpenAudio,
|
||||
value,
|
||||
onChange
|
||||
}: {
|
||||
isOpenAudio: boolean;
|
||||
value: AppWhisperConfigType;
|
||||
onChange: (e: AppWhisperConfigType) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
|
||||
const isOpenWhisper = value.open;
|
||||
const isAutoSend = value.autoSend;
|
||||
|
||||
const formLabel = useMemo(() => {
|
||||
if (!isOpenWhisper) {
|
||||
return t('core.app.whisper.Close');
|
||||
}
|
||||
return t('core.app.whisper.Open');
|
||||
}, [t, isOpenWhisper]);
|
||||
|
||||
return (
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/app/simpleMode/whisper'} mr={2} w={'20px'} />
|
||||
<Box>{t('core.app.Whisper')}</Box>
|
||||
<Box flex={1} />
|
||||
<MyTooltip label={t('core.app.Config whisper')}>
|
||||
<Button
|
||||
variant={'transparentBase'}
|
||||
iconSpacing={1}
|
||||
size={'sm'}
|
||||
fontSize={'md'}
|
||||
mr={'-5px'}
|
||||
onClick={onOpen}
|
||||
>
|
||||
{formLabel}
|
||||
</Button>
|
||||
</MyTooltip>
|
||||
<MyModal
|
||||
title={t('core.app.Whisper config')}
|
||||
iconSrc="core/app/simpleMode/whisper"
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
>
|
||||
<ModalBody px={[5, 16]} py={[4, 8]}>
|
||||
<Flex justifyContent={'space-between'} alignItems={'center'}>
|
||||
{t('core.app.whisper.Switch')}
|
||||
<Switch
|
||||
isChecked={isOpenWhisper}
|
||||
size={'lg'}
|
||||
onChange={(e) => {
|
||||
onChange({
|
||||
...value,
|
||||
open: e.target.checked
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
{isOpenWhisper && (
|
||||
<Flex mt={8} alignItems={'center'}>
|
||||
{t('core.app.whisper.Auto send')}
|
||||
<QuestionTip label={t('core.app.whisper.Auto send tip')} />
|
||||
<Box flex={'1 0 0'} />
|
||||
<Switch
|
||||
isChecked={value.autoSend}
|
||||
size={'lg'}
|
||||
onChange={(e) => {
|
||||
onChange({
|
||||
...value,
|
||||
autoSend: e.target.checked
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
{isOpenWhisper && isAutoSend && (
|
||||
<>
|
||||
<Flex mt={8} alignItems={'center'}>
|
||||
{t('core.app.whisper.Auto tts response')}
|
||||
<QuestionTip label={t('core.app.whisper.Auto tts response tip')} />
|
||||
<Box flex={'1 0 0'} />
|
||||
<Switch
|
||||
isChecked={value.autoTTSResponse}
|
||||
size={'lg'}
|
||||
onChange={(e) => {
|
||||
onChange({
|
||||
...value,
|
||||
autoTTSResponse: e.target.checked
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
{!isOpenAudio && (
|
||||
<Box mt={1} color={'myGray.600'} fontSize={'sm'}>
|
||||
{t('core.app.whisper.Not tts tip')}
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</ModalBody>
|
||||
</MyModal>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(WhisperConfig);
|
@@ -121,6 +121,7 @@ const ChatTest = (
|
||||
<Box flex={1}>
|
||||
<ChatBox
|
||||
ref={ChatBoxRef}
|
||||
appId={app._id}
|
||||
appAvatar={app.avatar}
|
||||
userAvatar={userInfo?.avatar}
|
||||
showMarkIcon
|
||||
|
@@ -16,13 +16,17 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { ChevronRightIcon } from '@chakra-ui/icons';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/module/node/constant';
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum
|
||||
} from '@fastgpt/global/core/module/node/constant';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import Divider from '../modules/Divider';
|
||||
import RenderToolInput from '../render/RenderToolInput';
|
||||
import RenderInput from '../render/RenderInput';
|
||||
import RenderOutput from '../render/RenderOutput';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
|
||||
const LafAccountModal = dynamic(() => import('@/components/support/laf/LafAccountModal'));
|
||||
|
||||
@@ -31,7 +35,7 @@ const NodeLaf = (props: NodeProps<FlowModuleItemType>) => {
|
||||
const { toast } = useToast();
|
||||
const { feConfigs } = useSystemStore();
|
||||
const { data, selected } = props;
|
||||
const { moduleId, inputs } = data;
|
||||
const { moduleId, inputs, outputs } = data;
|
||||
|
||||
const requestUrl = inputs.find((item) => item.key === ModuleInputKeyEnum.httpReqUrl);
|
||||
|
||||
@@ -49,7 +53,11 @@ const NodeLaf = (props: NodeProps<FlowModuleItemType>) => {
|
||||
);
|
||||
}
|
||||
|
||||
const { data: lafData, isLoading: isLoadingFunctions } = useQuery(
|
||||
const {
|
||||
data: lafData,
|
||||
isLoading: isLoadingFunctions,
|
||||
refetch: refetchFunction
|
||||
} = useQuery(
|
||||
['getLafFunctionList'],
|
||||
async () => {
|
||||
// load laf app detail
|
||||
@@ -94,61 +102,99 @@ const NodeLaf = (props: NodeProps<FlowModuleItemType>) => {
|
||||
[lafFunctionSelectList, requestUrl?.value]
|
||||
);
|
||||
|
||||
const onSyncParams = useCallback(() => {
|
||||
const lafFunction = lafData?.lafFunctions.find((item) => item.requestUrl === selectedFunction);
|
||||
const { mutate: onSyncParams, isLoading: isSyncing } = useRequest({
|
||||
mutationFn: async () => {
|
||||
await refetchFunction();
|
||||
const lafFunction = lafData?.lafFunctions.find(
|
||||
(item) => item.requestUrl === selectedFunction
|
||||
);
|
||||
|
||||
if (!lafFunction) return;
|
||||
if (!lafFunction) return;
|
||||
|
||||
const bodyParams =
|
||||
lafFunction?.request?.content?.['application/json']?.schema?.properties || {};
|
||||
const bodyParams =
|
||||
lafFunction?.request?.content?.['application/json']?.schema?.properties || {};
|
||||
|
||||
const requiredParams =
|
||||
lafFunction?.request?.content?.['application/json']?.schema?.required || [];
|
||||
const requiredParams =
|
||||
lafFunction?.request?.content?.['application/json']?.schema?.required || [];
|
||||
|
||||
const allParams = [
|
||||
...Object.keys(bodyParams).map((key) => ({
|
||||
name: key,
|
||||
desc: bodyParams[key].description,
|
||||
required: requiredParams?.includes(key) || false,
|
||||
value: `{{${key}}}`,
|
||||
type: 'string'
|
||||
}))
|
||||
].filter((item) => !inputs.find((input) => input.key === item.name));
|
||||
const allParams = [
|
||||
...Object.keys(bodyParams).map((key) => ({
|
||||
name: key,
|
||||
desc: bodyParams[key].description,
|
||||
required: requiredParams?.includes(key) || false,
|
||||
value: `{{${key}}}`,
|
||||
type: 'string'
|
||||
}))
|
||||
].filter((item) => !inputs.find((input) => input.key === item.name));
|
||||
|
||||
// add params
|
||||
allParams.forEach((param) => {
|
||||
onChangeNode({
|
||||
moduleId,
|
||||
type: 'addInput',
|
||||
key: param.name,
|
||||
value: {
|
||||
// add params
|
||||
allParams.forEach((param) => {
|
||||
onChangeNode({
|
||||
moduleId,
|
||||
type: 'addInput',
|
||||
key: param.name,
|
||||
valueType: ModuleIOValueTypeEnum.string,
|
||||
label: param.name,
|
||||
type: FlowNodeInputTypeEnum.target,
|
||||
required: param.required,
|
||||
description: param.desc || '',
|
||||
toolDescription: param.desc || '未设置参数描述',
|
||||
edit: true,
|
||||
editField: {
|
||||
key: true,
|
||||
name: true,
|
||||
description: true,
|
||||
required: true,
|
||||
dataType: true,
|
||||
inputType: true,
|
||||
isToolInput: true
|
||||
},
|
||||
connected: false
|
||||
}
|
||||
value: {
|
||||
key: param.name,
|
||||
valueType: ModuleIOValueTypeEnum.string,
|
||||
label: param.name,
|
||||
type: FlowNodeInputTypeEnum.target,
|
||||
required: param.required,
|
||||
description: param.desc || '',
|
||||
toolDescription: param.desc || '未设置参数描述',
|
||||
edit: true,
|
||||
editField: {
|
||||
key: true,
|
||||
name: true,
|
||||
description: true,
|
||||
required: true,
|
||||
dataType: true,
|
||||
inputType: true,
|
||||
isToolInput: true
|
||||
},
|
||||
connected: false
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
toast({
|
||||
status: 'success',
|
||||
title: t('common.Sync success')
|
||||
});
|
||||
}, [inputs, lafData?.lafFunctions, moduleId, selectedFunction, t, toast]);
|
||||
const responseParams =
|
||||
lafFunction?.response?.default.content?.['application/json'].schema.properties || {};
|
||||
const requiredResponseParams =
|
||||
lafFunction?.response?.default.content?.['application/json'].schema.required || [];
|
||||
|
||||
const allResponseParams = [
|
||||
...Object.keys(responseParams).map((key) => ({
|
||||
valueType: responseParams[key].type,
|
||||
name: key,
|
||||
desc: responseParams[key].description,
|
||||
required: requiredResponseParams?.includes(key) || false
|
||||
}))
|
||||
].filter((item) => !outputs.find((output) => output.key === item.name));
|
||||
allResponseParams.forEach((param) => {
|
||||
onChangeNode({
|
||||
moduleId,
|
||||
type: 'addOutput',
|
||||
key: param.name,
|
||||
value: {
|
||||
key: param.name,
|
||||
valueType: param.valueType,
|
||||
label: param.name,
|
||||
type: FlowNodeOutputTypeEnum.source,
|
||||
required: param.required,
|
||||
description: param.desc || '',
|
||||
edit: true,
|
||||
editField: {
|
||||
key: true,
|
||||
description: true,
|
||||
dataType: true,
|
||||
defaultValue: true
|
||||
},
|
||||
targets: []
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
successToast: t('common.Sync success')
|
||||
});
|
||||
|
||||
return (
|
||||
<NodeCard minW={'350px'} selected={selected} {...data}>
|
||||
@@ -174,9 +220,9 @@ const NodeLaf = (props: NodeProps<FlowModuleItemType>) => {
|
||||
{/* auto set params and go to edit */}
|
||||
{!!selectedFunction && (
|
||||
<Flex justifyContent={'flex-end'} mt={2} gap={2}>
|
||||
{/* <Button variant={'whiteBase'} size={'sm'} onClick={onSyncParams}>
|
||||
<Button isLoading={isSyncing} variant={'grayBase'} size={'sm'} onClick={onSyncParams}>
|
||||
{t('core.module.Laf sync params')}
|
||||
</Button> */}
|
||||
</Button>
|
||||
<Button
|
||||
variant={'grayBase'}
|
||||
size={'sm'}
|
||||
|
@@ -7,14 +7,14 @@ import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||
import { welcomeTextTip } from '@fastgpt/global/core/module/template/tip';
|
||||
import { onChangeNode } from '../../FlowProvider';
|
||||
|
||||
import VariableEdit from '../modules/VariableEdit';
|
||||
import VariableEdit from '../../../../app/VariableEdit';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import MyTooltip from '@/components/MyTooltip';
|
||||
import Container from '../modules/Container';
|
||||
import NodeCard from '../render/NodeCard';
|
||||
import type { VariableItemType } from '@fastgpt/global/core/module/type.d';
|
||||
import QGSwitch from '@/components/core/module/Flow/components/modules/QGSwitch';
|
||||
import TTSSelect from '@/components/core/module/Flow/components/modules/TTSSelect';
|
||||
import type { VariableItemType } from '@fastgpt/global/core/app/type.d';
|
||||
import QGSwitch from '@/components/core/app/QGSwitch';
|
||||
import TTSSelect from '@/components/core/app/TTSSelect';
|
||||
import { splitGuideModule } from '@fastgpt/global/core/module/utils';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
|
Reference in New Issue
Block a user