perf: gate

This commit is contained in:
archer 2025-05-30 17:02:49 +08:00
parent 81202c53a8
commit ded0383ac4
No known key found for this signature in database
GPG Key ID: 4446499B846D4A9E
9 changed files with 80 additions and 59 deletions

View File

@ -46,7 +46,7 @@ export const appWorkflow2Form = ({
chatConfig chatConfig
}: { }: {
nodes: StoreNodeItemType[]; nodes: StoreNodeItemType[];
chatConfig: AppChatConfigType; chatConfig?: AppChatConfigType;
}) => { }) => {
const defaultAppForm = getDefaultAppForm(); const defaultAppForm = getDefaultAppForm();
const findInputValueByKey = (inputs: FlowNodeInputItemType[], key: string) => { const findInputValueByKey = (inputs: FlowNodeInputItemType[], key: string) => {
@ -172,6 +172,10 @@ export const appWorkflow2Form = ({
} }
}); });
if (chatConfig) {
defaultAppForm.chatConfig = chatConfig;
}
return defaultAppForm; return defaultAppForm;
}; };

View File

@ -281,7 +281,7 @@ const ChatInput = ({
[ [
File, File,
TextareaDom, TextareaDom,
fileList, fileList.length,
handleSend, handleSend,
hasFileUploading, hasFileUploading,
havInput, havInput,
@ -296,7 +296,8 @@ const ChatInput = ({
setValue, setValue,
showSelectFile, showSelectFile,
showSelectImg, showSelectImg,
t t,
whisperConfig?.open
] ]
); );

View File

@ -83,7 +83,6 @@ const GateChatInput = ({
const selectedTools = externalSelectedToolIds ?? []; const selectedTools = externalSelectedToolIds ?? [];
const setSelectedToolIds = onSelectTools!; const setSelectedToolIds = onSelectTools!;
const { appDetail } = useContextSelector(AppContext, (v) => v);
const { llmModelList } = useSystemStore(); const { llmModelList } = useSystemStore();
const modelList = useMemo( const modelList = useMemo(
() => llmModelList.map((item) => ({ label: item.name, value: item.model })), () => llmModelList.map((item) => ({ label: item.name, value: item.model })),
@ -101,36 +100,6 @@ const GateChatInput = ({
return router.pathname === '/chat/gate'; return router.pathname === '/chat/gate';
}, [router.pathname]); }, [router.pathname]);
// 初始化加载appForm - 从Gate应用获取配置
useEffect(() => {
if (!appId || !showTools) return;
const fetchAppForm = async () => {
try {
// 加载Gate应用列表
// 获取当前应用或第一个可用的Gate应用
const currentApp = appDetail;
if (currentApp && currentApp.modules) {
// 将模块转换为appForm格式
const form = appWorkflow2Form({
nodes: currentApp.modules,
chatConfig: currentApp.chatConfig || {}
});
setAppForm(form);
// 如果选择了模型,设置为默认模型
if (form.aiSettings.model) {
setSelectedModel(form.aiSettings.model);
}
}
} catch (error) {
console.error('加载Gate应用信息失败:', error);
}
};
fetchAppForm();
}, [appId, showTools, appDetail, setAppForm]);
// 当模型选择变化时更新appForm // 当模型选择变化时更新appForm
useEffect(() => { useEffect(() => {
if (!showTools) return; if (!showTools) return;
@ -230,15 +199,6 @@ const GateChatInput = ({
<FilePreview fileList={fileList} removeFiles={removeFiles} /> <FilePreview fileList={fileList} removeFiles={removeFiles} />
</Box> </Box>
{/* voice input and loading container */}
{!inputValue && (
<VoiceInput
ref={VoiceInputRef}
onSendMessage={onSendMessage}
resetInputVal={resetInputVal}
/>
)}
<Textarea <Textarea
ref={TextareaDom} ref={TextareaDom}
value={inputValue} value={inputValue}
@ -451,6 +411,15 @@ const GateChatInput = ({
<File onSelect={(files) => onSelectFile({ files })} /> <File onSelect={(files) => onSelectFile({ files })} />
<ComplianceTip type={'chat'} /> <ComplianceTip type={'chat'} />
{/* voice input and loading container */}
{!inputValue && (
<VoiceInput
ref={VoiceInputRef}
onSendMessage={onSendMessage}
resetInputVal={resetInputVal}
/>
)}
</Box> </Box>
); );
}; };

View File

@ -6,12 +6,10 @@ import React, {
useCallback, useCallback,
useState, useState,
forwardRef, forwardRef,
useImperativeHandle, useImperativeHandle
useMemo
} from 'react'; } from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { useSystem } from '@fastgpt/web/hooks/useSystem'; import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { useContextSelector } from 'use-context-selector'; import { useContextSelector } from 'use-context-selector';
import { ChatBoxContext } from '../Provider'; import { ChatBoxContext } from '../Provider';

View File

@ -14,6 +14,7 @@ import type { putUpdateGateConfigCopyRightData } from '@fastgpt/global/support/u
import { saveCopyRightConfig } from './CopyrightTable'; import { saveCopyRightConfig } from './CopyrightTable';
import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type'; import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type';
import { form2AppWorkflow } from '@/web/core/app/utils'; import { form2AppWorkflow } from '@/web/core/app/utils';
import { useSystemStore } from '@/web/common/system/useSystemStore';
type Props = { type Props = {
tab: 'home' | 'copyright' | 'app' | 'logs'; tab: 'home' | 'copyright' | 'app' | 'logs';
@ -84,6 +85,7 @@ const ConfigButtons = ({ tab, appForm, gateConfig, copyRightConfig }: Props) =>
} }
); );
const { ttsModelList, sttModelList } = useSystemStore();
const checkAndCreateGateApp = async () => { const checkAndCreateGateApp = async () => {
try { try {
// 获取应用列表 // 获取应用列表
@ -103,7 +105,27 @@ const ConfigButtons = ({ tab, appForm, gateConfig, copyRightConfig }: Props) =>
intro: currentSlogan, intro: currentSlogan,
name: gateConfig?.name, name: gateConfig?.name,
nodes, nodes,
edges edges,
chatConfig: {
ttsConfig:
ttsModelList.length > 0
? {
type: 'model',
model: ttsModelList[0].model
}
: undefined,
whisperConfig: {
open: sttModelList.length > 0,
autoSend: false,
autoTTSResponse: false
},
fileSelectConfig: {
canSelectFile: true,
customPdfParse: false,
canSelectImg: true,
maxFiles: 10
}
}
}); });
} }
} else { } else {
@ -114,7 +136,26 @@ const ConfigButtons = ({ tab, appForm, gateConfig, copyRightConfig }: Props) =>
type: AppTypeEnum.gate, type: AppTypeEnum.gate,
modules: emptyTemplates[AppTypeEnum.gate].nodes, modules: emptyTemplates[AppTypeEnum.gate].nodes,
edges: emptyTemplates[AppTypeEnum.gate].edges, edges: emptyTemplates[AppTypeEnum.gate].edges,
chatConfig: emptyTemplates[AppTypeEnum.gate].chatConfig chatConfig: {
ttsConfig:
ttsModelList.length > 0
? {
type: 'model',
model: ttsModelList[0].model
}
: undefined,
whisperConfig: {
open: sttModelList.length > 0,
autoSend: false,
autoTTSResponse: false
},
fileSelectConfig: {
canSelectFile: true,
customPdfParse: false,
canSelectImg: true,
maxFiles: 10
}
}
}); });
} }
} catch (error) { } catch (error) {

View File

@ -36,6 +36,7 @@ import {
batchRemoveTagsFromApp batchRemoveTagsFromApp
} from '@/web/core/app/api/tags'; } from '@/web/core/app/api/tags';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { useSystemStore } from '@/web/common/system/useSystemStore';
interface AppInfoModalProps { interface AppInfoModalProps {
app: AppListItemType; app: AppListItemType;
@ -52,6 +53,8 @@ const AppInfoModal = ({ app, onClose, onUpdateSuccess }: AppInfoModalProps) => {
const [initialTags, setInitialTags] = useState<string[]>(app.tags || []); const [initialTags, setInitialTags] = useState<string[]>(app.tags || []);
const [refreshTrigger, setRefreshTrigger] = useState(0); const [refreshTrigger, setRefreshTrigger] = useState(0);
const { ttsModelList, sttModelList } = useSystemStore();
const { const {
File, File,
onOpen: onOpenSelectFile, onOpen: onOpenSelectFile,

View File

@ -153,7 +153,7 @@ export const useChatGate = ({
const { data: recommendApps = [] } = useRequest2(listQuickApps, { const { data: recommendApps = [] } = useRequest2(listQuickApps, {
manual: false manual: false
}); });
console.log(appForm, 111);
const CustomChatContainer = useMemoizedFn(() => ( const CustomChatContainer = useMemoizedFn(() => (
<ChatBox <ChatBox
isReady={isReady} isReady={isReady}

View File

@ -10,6 +10,7 @@ import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controlle
import { NextAPI } from '@/service/middleware/entry'; import { NextAPI } from '@/service/middleware/entry';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
async function handler( async function handler(
req: NextApiRequest, req: NextApiRequest,
@ -42,7 +43,13 @@ async function handler(
} }
// get app and history // get app and history
const { nodes, chatConfig } = await getAppLatestVersion(app._id, app); const { nodes, chatConfig } =
app.type === AppTypeEnum.gate
? {
nodes: app.modules,
chatConfig: app.chatConfig
}
: await getAppLatestVersion(app._id, app);
const pluginInputs = const pluginInputs =
chat?.pluginInputs ?? chat?.pluginInputs ??
nodes?.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)?.inputs ?? nodes?.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)?.inputs ??

View File

@ -124,17 +124,15 @@ const Chat = ({
}); });
// 如果还没有 AppDetail则重新获取 // 如果还没有 AppDetail则重新获取
if (!appDetail && appId) { if (appId) {
try { try {
const detail = await getAppDetailById(appId); const detail = await getAppDetailById(appId);
if (detail?.modules) { const form = appWorkflow2Form({
setAppDetail(detail); nodes: detail.modules,
const form = appWorkflow2Form({ chatConfig: detail.chatConfig || {}
nodes: detail.modules, });
chatConfig: detail.chatConfig || {} setAppDetail(detail);
}); setAppForm(form);
setAppForm(form);
}
} catch (error) { } catch (error) {
console.error('Failed to fetch app detail:', error); console.error('Failed to fetch app detail:', error);
} }