From d682a8252fbe102619c8ccd8358af10c99d0fe62 Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Thu, 8 Aug 2024 17:45:15 +0800 Subject: [PATCH] 4.8.9 test (#2299) * perf: read file prompt * perf: read file prompt * perf: free plan tip * feat: cron job usage * perf: app templates * perf: get llm model by name * feat: support outlink upload file * fix: upload limit --- packages/service/core/ai/model.ts | 18 +- .../core/workflow/dispatch/tools/readFiles.ts | 2 +- .../app/public/imgs/app/templates/flux.svg | 1 + .../core/ai/AISettingModal/index.tsx | 9 +- .../ChatContainer/ChatBox/Input/ChatInput.tsx | 3 +- .../core/dataset/SearchParamsTip.tsx | 8 +- .../app/src/pages/api/common/file/upload.ts | 41 +- .../detail/components/SimpleApp/EditForm.tsx | 4 +- .../Flow/nodes/NodeDatasetConcat.tsx | 4 +- .../templates/SelectDatasetParams.tsx | 4 +- projects/app/src/pages/chat/index.tsx | 2 +- projects/app/src/pages/chat/share.tsx | 2 +- projects/app/src/pages/chat/team.tsx | 2 +- .../service/support/permission/auth/chat.ts | 10 +- .../app/src/web/common/file/controller.ts | 11 + projects/app/src/web/common/system/utils.ts | 7 + projects/app/src/web/core/app/templates.ts | 1705 ++++++++++------- projects/app/src/web/core/chat/utils.ts | 5 +- 18 files changed, 1056 insertions(+), 782 deletions(-) create mode 100644 projects/app/public/imgs/app/templates/flux.svg diff --git a/packages/service/core/ai/model.ts b/packages/service/core/ai/model.ts index 696815c7afa..2d7ef0f98fd 100644 --- a/packages/service/core/ai/model.ts +++ b/packages/service/core/ai/model.ts @@ -1,20 +1,28 @@ export const getLLMModel = (model?: string) => { - return global.llmModels.find((item) => item.model === model) ?? global.llmModels[0]; + return ( + global.llmModels.find((item) => item.model === model || item.name === model) ?? + global.llmModels[0] + ); }; export const getDatasetModel = (model?: string) => { return ( - global.llmModels?.filter((item) => item.datasetProcess)?.find((item) => item.model === model) ?? - global.llmModels[0] + global.llmModels + ?.filter((item) => item.datasetProcess) + ?.find((item) => item.model === model || item.name === model) ?? global.llmModels[0] ); }; export const getVectorModel = (model?: string) => { - return global.vectorModels.find((item) => item.model === model) || global.vectorModels[0]; + return ( + global.vectorModels.find((item) => item.model === model || item.name === model) || + global.vectorModels[0] + ); }; export function getAudioSpeechModel(model?: string) { return ( - global.audioSpeechModels.find((item) => item.model === model) || global.audioSpeechModels[0] + global.audioSpeechModels.find((item) => item.model === model || item.name === model) || + global.audioSpeechModels[0] ); } diff --git a/packages/service/core/workflow/dispatch/tools/readFiles.ts b/packages/service/core/workflow/dispatch/tools/readFiles.ts index 3a2b85a72be..67914cf04c8 100644 --- a/packages/service/core/workflow/dispatch/tools/readFiles.ts +++ b/packages/service/core/workflow/dispatch/tools/readFiles.ts @@ -95,7 +95,7 @@ export const dispatchReadFiles = async (props: Props): Promise => { }) .filter(Boolean) .slice(0, maxFiles); - console.log(parseUrlList); + const readFilesResult = await Promise.all( parseUrlList .map(async (url) => { diff --git a/projects/app/public/imgs/app/templates/flux.svg b/projects/app/public/imgs/app/templates/flux.svg new file mode 100644 index 00000000000..dfa377fff32 --- /dev/null +++ b/projects/app/public/imgs/app/templates/flux.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/app/src/components/core/ai/AISettingModal/index.tsx b/projects/app/src/components/core/ai/AISettingModal/index.tsx index 20cdd463577..3487086a3a7 100644 --- a/projects/app/src/components/core/ai/AISettingModal/index.tsx +++ b/projects/app/src/components/core/ai/AISettingModal/index.tsx @@ -20,6 +20,7 @@ import { getDocPath } from '@/web/common/system/doc'; import AIModelSelector from '@/components/Select/AIModelSelector'; import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; +import { getWebLLMModel } from '@/web/common/system/utils'; const AIChatSettingsModal = ({ onClose, @@ -44,18 +45,18 @@ const AIChatSettingsModal = ({ const showVisionSwitch = watch(NodeInputKeyEnum.aiChatVision) !== undefined; const showMaxHistoriesSlider = watch('maxHistories') !== undefined; const useVision = watch('aiChatVision'); - const selectedModel = llmModelList.find((item) => item.model === model) || llmModelList[0]; + const selectedModel = getWebLLMModel(model); const llmSupportVision = !!selectedModel?.vision; const tokenLimit = useMemo(() => { - return llmModelList.find((item) => item.model === model)?.maxResponse || 4096; - }, [llmModelList, model]); + return selectedModel?.maxResponse || 4096; + }, [selectedModel?.maxResponse]); const onChangeModel = (e: string) => { setValue('model', e); // update max tokens - const modelData = llmModelList.find((item) => item.model === e); + const modelData = getWebLLMModel(e); if (modelData) { setValue('maxToken', modelData.maxResponse / 2); } diff --git a/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx b/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx index 671aba68a2d..5fa3f8a55cd 100644 --- a/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx +++ b/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx @@ -137,6 +137,7 @@ const ChatInput = ({ const { previewUrl } = await uploadFile2DB({ file: copyFile.rawFile, bucketName: 'chat', + outLinkAuthData, metadata: { chatId }, @@ -168,7 +169,7 @@ const ChatInput = ({ { manual: false, errorToast: t('common:upload_file_error'), - refreshDeps: [fileList] + refreshDeps: [fileList, outLinkAuthData, chatId] } ); const onSelectFile = useCallback( diff --git a/projects/app/src/components/core/dataset/SearchParamsTip.tsx b/projects/app/src/components/core/dataset/SearchParamsTip.tsx index 5648a107c06..389772bd87e 100644 --- a/projects/app/src/components/core/dataset/SearchParamsTip.tsx +++ b/projects/app/src/components/core/dataset/SearchParamsTip.tsx @@ -7,6 +7,7 @@ import { import { useTranslation } from 'next-i18next'; import React, { useMemo } from 'react'; import MyIcon from '@fastgpt/web/components/common/Icon'; +import { getWebLLMModel } from '@/web/common/system/utils'; const SearchParamsTip = ({ searchMode, @@ -34,11 +35,8 @@ const SearchParamsTip = ({ const extensionModelName = useMemo( () => - datasetSearchUsingExtensionQuery - ? llmModelList.find((item) => item.model === queryExtensionModel)?.name ?? - llmModelList[0]?.name - : undefined, - [datasetSearchUsingExtensionQuery, llmModelList, queryExtensionModel] + datasetSearchUsingExtensionQuery ? getWebLLMModel(queryExtensionModel)?.name : undefined, + [datasetSearchUsingExtensionQuery, queryExtensionModel, llmModelList] ); return ( diff --git a/projects/app/src/pages/api/common/file/upload.ts b/projects/app/src/pages/api/common/file/upload.ts index 6c9451396b4..da2726184f4 100644 --- a/projects/app/src/pages/api/common/file/upload.ts +++ b/projects/app/src/pages/api/common/file/upload.ts @@ -1,6 +1,5 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@fastgpt/service/common/response'; -import { authCert } from '@fastgpt/service/support/permission/auth/common'; import { uploadFile } from '@fastgpt/service/common/file/gridfs/controller'; import { getUploadModel } from '@fastgpt/service/common/file/multer'; import { removeFilesByPaths } from '@fastgpt/service/common/file/utils'; @@ -10,6 +9,7 @@ import { ReadFileBaseUrl } from '@fastgpt/global/common/file/constants'; import { addLog } from '@fastgpt/service/common/system/log'; import { authFrequencyLimit } from '@/service/common/frequencyLimit/api'; import { addSeconds } from 'date-fns'; +import { authChatCert } from '@/service/support/permission/auth/chat'; const authUploadLimit = (tmbId: string) => { if (!global.feConfigs.uploadFileMaxAmount) return; @@ -21,19 +21,18 @@ const authUploadLimit = (tmbId: string) => { }; async function handler(req: NextApiRequest, res: NextApiResponse) { - const start = Date.now(); - /* Creates the multer uploader */ - const upload = getUploadModel({ - maxSize: (global.feConfigs?.uploadFileMaxSize || 500) * 1024 * 1024 - }); const filePaths: string[] = []; - try { - const { teamId, tmbId } = await authCert({ req, authToken: true }); + const start = Date.now(); + /* Creates the multer uploader */ + const upload = getUploadModel({ + maxSize: (global.feConfigs?.uploadFileMaxSize || 500) * 1024 * 1024 + }); + const { file, bucketName, metadata } = await upload.doUpload(req, res); - await authUploadLimit(tmbId); + const { teamId, tmbId, outLinkUid } = await authChatCert({ req, authToken: true }); - const { file, bucketName, metadata } = await upload.doUpload(req, res); + await authUploadLimit(outLinkUid || tmbId); addLog.info(`Upload file success ${file.originalname}, cost ${Date.now() - start}ms`); @@ -51,15 +50,19 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { metadata: metadata }); - return { - fileId, - previewUrl: `${ReadFileBaseUrl}?filename=${file.originalname}&token=${await createFileToken({ - bucketName, - teamId, - tmbId, - fileId - })}` - }; + jsonRes(res, { + data: { + fileId, + previewUrl: `${ReadFileBaseUrl}?filename=${file.originalname}&token=${await createFileToken( + { + bucketName, + teamId, + tmbId, + fileId + } + )}` + } + }); } catch (error) { jsonRes(res, { code: 500, diff --git a/projects/app/src/pages/app/detail/components/SimpleApp/EditForm.tsx b/projects/app/src/pages/app/detail/components/SimpleApp/EditForm.tsx index 60b4f051415..0ee1985c00c 100644 --- a/projects/app/src/pages/app/detail/components/SimpleApp/EditForm.tsx +++ b/projects/app/src/pages/app/detail/components/SimpleApp/EditForm.tsx @@ -35,6 +35,7 @@ import { AppContext } from '@/pages/app/detail/components/context'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel'; import VariableTip from '@/components/common/Textarea/MyTextarea/VariableTip'; +import { getWebLLMModel } from '@/web/common/system/utils'; const DatasetSelectModal = dynamic(() => import('@/components/core/app/DatasetSelectModal')); const DatasetParamsModal = dynamic(() => import('@/components/core/app/DatasetParamsModal')); @@ -121,8 +122,7 @@ const EditForm = ({ [appForm.chatConfig.variables, t] ); - const selectedModel = - llmModelList.find((item) => item.model === appForm.aiSettings.model) ?? llmModelList[0]; + const selectedModel = getWebLLMModel(appForm.aiSettings.model); const tokenLimit = useMemo(() => { return selectedModel?.quoteMaxToken || 3000; }, [selectedModel.quoteMaxToken]); diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeDatasetConcat.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeDatasetConcat.tsx index 16f5d784e11..1585ea98144 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeDatasetConcat.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeDatasetConcat.tsx @@ -29,6 +29,7 @@ import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel'; import ValueTypeLabel from './render/ValueTypeLabel'; import MyIcon from '@fastgpt/web/components/common/Icon'; import { isWorkflowStartOutput } from '@fastgpt/global/core/workflow/template/system/workflowStart'; +import { getWebLLMModel } from '@/web/common/system/utils'; const NodeDatasetConcat = ({ data, selected }: NodeProps) => { const { t } = useTranslation(); @@ -46,8 +47,7 @@ const NodeDatasetConcat = ({ data, selected }: NodeProps) => { if (item.flowNodeType === FlowNodeTypeEnum.chatNode) { const model = item.inputs.find((item) => item.key === NodeInputKeyEnum.aiModel)?.value || ''; - const quoteMaxToken = - llmModelList.find((item) => item.model === model)?.quoteMaxToken || 3000; + const quoteMaxToken = getWebLLMModel(model)?.quoteMaxToken || 3000; maxTokens = Math.max(maxTokens, quoteMaxToken); } diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SelectDatasetParams.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SelectDatasetParams.tsx index ebe8e144be5..ec7ae319ed5 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SelectDatasetParams.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SelectDatasetParams.tsx @@ -11,6 +11,7 @@ import { useSystemStore } from '@/web/common/system/useSystemStore'; import SearchParamsTip from '@/components/core/dataset/SearchParamsTip'; import { useContextSelector } from 'use-context-selector'; import { WorkflowContext } from '@/pages/app/detail/components/WorkflowComponents/context'; +import { getWebLLMModel } from '@/web/common/system/utils'; const SelectDatasetParam = ({ inputs = [], nodeId }: RenderInputProps) => { const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode); @@ -36,8 +37,7 @@ const SelectDatasetParam = ({ inputs = [], nodeId }: RenderInputProps) => { if (item.flowNodeType === FlowNodeTypeEnum.chatNode) { const model = item.inputs.find((item) => item.key === NodeInputKeyEnum.aiModel)?.value || ''; - const quoteMaxToken = - llmModelList.find((item) => item.model === model)?.quoteMaxToken || 3000; + const quoteMaxToken = getWebLLMModel(model)?.quoteMaxToken || 3000; maxTokens = Math.max(maxTokens, quoteMaxToken); } diff --git a/projects/app/src/pages/chat/index.tsx b/projects/app/src/pages/chat/index.tsx index d588e8772f7..b391ba0017d 100644 --- a/projects/app/src/pages/chat/index.tsx +++ b/projects/app/src/pages/chat/index.tsx @@ -338,7 +338,7 @@ export async function getServerSideProps(context: any) { props: { appId: context?.query?.appId || '', chatId: context?.query?.chatId || '', - ...(await serviceSideProps(context, ['file', 'app', 'chat'])) + ...(await serviceSideProps(context, ['file', 'app', 'chat', 'workflow'])) } }; } diff --git a/projects/app/src/pages/chat/share.tsx b/projects/app/src/pages/chat/share.tsx index 03deab02bd0..cbca91f0a5d 100644 --- a/projects/app/src/pages/chat/share.tsx +++ b/projects/app/src/pages/chat/share.tsx @@ -394,7 +394,7 @@ export async function getServerSideProps(context: any) { appIntro: app?.appId?.intro ?? 'intro', shareId: shareId ?? '', authToken: authToken ?? '', - ...(await serviceSideProps(context, ['file', 'app', 'chat'])) + ...(await serviceSideProps(context, ['file', 'app', 'chat', 'workflow'])) } }; } diff --git a/projects/app/src/pages/chat/team.tsx b/projects/app/src/pages/chat/team.tsx index 91255c39c9e..c3e023d4a41 100644 --- a/projects/app/src/pages/chat/team.tsx +++ b/projects/app/src/pages/chat/team.tsx @@ -337,7 +337,7 @@ export async function getServerSideProps(context: any) { chatId: context?.query?.chatId || '', teamId: context?.query?.teamId || '', teamToken: context?.query?.teamToken || '', - ...(await serviceSideProps(context, ['file', 'app', 'chat'])) + ...(await serviceSideProps(context, ['file', 'app', 'chat', 'workflow'])) } }; } diff --git a/projects/app/src/service/support/permission/auth/chat.ts b/projects/app/src/service/support/permission/auth/chat.ts index e6202518a83..d72426335a2 100644 --- a/projects/app/src/service/support/permission/auth/chat.ts +++ b/projects/app/src/service/support/permission/auth/chat.ts @@ -103,7 +103,15 @@ export async function authChatCrud({ 3. share page (body: shareId outLinkUid) 4. team chat page (body: teamId teamToken) */ -export async function authChatCert(props: AuthModeType) { +export async function authChatCert(props: AuthModeType): Promise<{ + teamId: string; + tmbId: string; + authType: AuthUserTypeEnum; + apikey: string; + isOwner: boolean; + canWrite: boolean; + outLinkUid?: string; +}> { const { teamId, teamToken, shareId, outLinkUid } = props.req.body as OutLinkChatAuthProps; if (shareId && outLinkUid) { diff --git a/projects/app/src/web/common/file/controller.ts b/projects/app/src/web/common/file/controller.ts index dd616255cbf..c0ec17d9d11 100644 --- a/projects/app/src/web/common/file/controller.ts +++ b/projects/app/src/web/common/file/controller.ts @@ -3,6 +3,7 @@ import { UploadImgProps } from '@fastgpt/global/common/file/api'; import { BucketNameEnum } from '@fastgpt/global/common/file/constants'; import { preUploadImgProps } from '@fastgpt/global/common/file/api'; import { compressBase64Img, type CompressImgProps } from '@fastgpt/web/common/file/img'; +import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat'; /** * upload file to mongo gridfs @@ -10,11 +11,13 @@ import { compressBase64Img, type CompressImgProps } from '@fastgpt/web/common/fi export const uploadFile2DB = ({ file, bucketName, + outLinkAuthData, metadata = {}, percentListen }: { file: File; bucketName: `${BucketNameEnum}`; + outLinkAuthData?: OutLinkChatAuthProps; metadata?: Record; percentListen?: (percent: number) => void; }) => { @@ -22,6 +25,14 @@ export const uploadFile2DB = ({ form.append('metadata', JSON.stringify(metadata)); form.append('bucketName', bucketName); form.append('file', file, encodeURIComponent(file.name)); + + if (outLinkAuthData) { + for (const key in outLinkAuthData) { + // @ts-ignore + outLinkAuthData[key] && form.append(key, outLinkAuthData[key]); + } + } + return postUploadFiles(form, (e) => { if (!e.total) return; diff --git a/projects/app/src/web/common/system/utils.ts b/projects/app/src/web/common/system/utils.ts index deee1f9317a..3d5ea1ef8a9 100644 --- a/projects/app/src/web/common/system/utils.ts +++ b/projects/app/src/web/common/system/utils.ts @@ -1,3 +1,5 @@ +import { useSystemStore } from './useSystemStore'; + export const downloadFetch = async ({ url, filename }: { url: string; filename: string }) => { const a = document.createElement('a'); a.href = url; @@ -6,3 +8,8 @@ export const downloadFetch = async ({ url, filename }: { url: string; filename: a.click(); document.body.removeChild(a); }; + +export const getWebLLMModel = (model?: string) => { + const list = useSystemStore.getState().llmModelList; + return list.find((item) => item.model === model || item.name === model) ?? list[0]; +}; diff --git a/projects/app/src/web/core/app/templates.ts b/projects/app/src/web/core/app/templates.ts index 2a4df5796ac..01037dc9731 100644 --- a/projects/app/src/web/core/app/templates.ts +++ b/projects/app/src/web/core/app/templates.ts @@ -1011,6 +1011,110 @@ export const simpleBotTemplates: TemplateType = [ ]; export const workflowTemplates: TemplateType = [ + { + id: 'workflow-default', + avatar: 'core/app/type/workflowFill', + name: '空白工作流', + intro: '从零开始构建工作流', + type: AppTypeEnum.workflow, + modules: [ + { + nodeId: 'userGuide', + name: '系统配置', + intro: '可以配置应用的系统参数', + avatar: 'core/workflow/template/systemConfig', + flowNodeType: 'userGuide', + position: { + x: 262.2732338817093, + y: -476.00241136598146 + }, + version: '481', + inputs: [ + { + key: 'welcomeText', + renderTypeList: ['hidden'], + valueType: 'string', + label: 'core.app.Welcome Text', + value: '' + }, + { + key: 'variables', + renderTypeList: ['hidden'], + valueType: 'any', + label: 'core.app.Chat Variable', + value: [] + }, + { + key: 'questionGuide', + valueType: 'boolean', + renderTypeList: ['hidden'], + label: 'core.app.Question Guide', + value: false + }, + { + key: 'tts', + renderTypeList: ['hidden'], + valueType: 'any', + label: '', + value: { + type: 'web' + } + }, + { + key: 'whisper', + renderTypeList: ['hidden'], + valueType: 'any', + label: '', + value: { + open: false, + autoSend: false, + autoTTSResponse: false + } + }, + { + key: 'scheduleTrigger', + renderTypeList: ['hidden'], + valueType: 'any', + label: '', + value: null + } + ], + outputs: [] + }, + { + nodeId: '448745', + name: '流程开始', + intro: '', + avatar: 'core/workflow/template/workflowStart', + flowNodeType: 'workflowStart', + position: { + x: 632.368838596004, + y: -347.7446492944009 + }, + version: '481', + inputs: [ + { + key: 'userChatInput', + renderTypeList: ['reference', 'textarea'], + valueType: 'string', + label: '用户问题', + required: true, + toolDescription: '用户问题' + } + ], + outputs: [ + { + id: 'userChatInput', + key: 'userChatInput', + label: 'common:core.module.input.label.user question', + type: 'static', + valueType: 'string' + } + ] + } + ], + edges: [] + }, { id: 'TranslateRobot', avatar: '/imgs/app/templates/translate.svg', @@ -2023,10 +2127,10 @@ export const workflowTemplates: TemplateType = [ ] }, { - id: 'dalle', - avatar: '/imgs/app/templates/dalle.svg', - name: 'Dalle3绘图', - intro: '通过请求Dalle3接口绘图,需要有 api key', + id: 'CQ', + avatar: 'core/workflow/template/questionClassify', + name: '问题分类 + 知识库', + intro: '先对用户的问题进行分类,再根据不同类型问题,执行不同的操作', type: AppTypeEnum.workflow, modules: [ { @@ -2034,7 +2138,7 @@ export const workflowTemplates: TemplateType = [ name: '系统配置', intro: '可以配置应用的系统参数', avatar: 'core/workflow/template/systemConfig', - flowNodeType: 'userGuide', + flowNodeType: FlowNodeTypeEnum.systemConfig, position: { x: 531.2422736065552, y: -486.7611729549753 @@ -2043,29 +2147,29 @@ export const workflowTemplates: TemplateType = [ inputs: [ { key: 'welcomeText', - renderTypeList: ['hidden'], - valueType: 'string', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + valueType: WorkflowIOValueTypeEnum.string, label: 'core.app.Welcome Text', - value: '' + value: '你好,我是知识库助手,请不要忘记选择知识库噢~\n[你是谁]\n[如何使用]' }, { key: 'variables', - renderTypeList: ['hidden'], - valueType: 'any', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + valueType: WorkflowIOValueTypeEnum.any, label: 'core.app.Chat Variable', value: [] }, { key: 'questionGuide', - valueType: 'boolean', - renderTypeList: ['hidden'], + valueType: WorkflowIOValueTypeEnum.boolean, + renderTypeList: [FlowNodeInputTypeEnum.hidden], label: 'core.app.Question Guide', - value: false + value: true }, { key: 'tts', - renderTypeList: ['hidden'], - valueType: 'any', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + valueType: WorkflowIOValueTypeEnum.any, label: '', value: { type: 'web' @@ -2073,8 +2177,8 @@ export const workflowTemplates: TemplateType = [ }, { key: 'whisper', - renderTypeList: ['hidden'], - valueType: 'any', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + valueType: WorkflowIOValueTypeEnum.any, label: '', value: { open: false, @@ -2084,8 +2188,8 @@ export const workflowTemplates: TemplateType = [ }, { key: 'scheduleTrigger', - renderTypeList: ['hidden'], - valueType: 'any', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + valueType: WorkflowIOValueTypeEnum.any, label: '', value: null } @@ -2093,21 +2197,21 @@ export const workflowTemplates: TemplateType = [ outputs: [] }, { - nodeId: '448745', + nodeId: 'workflowStartNodeId', name: '流程开始', intro: '', avatar: 'core/workflow/template/workflowStart', - flowNodeType: 'workflowStart', + flowNodeType: FlowNodeTypeEnum.workflowStart, position: { - x: 532.1275542407774, - y: 46.03775600322817 + x: 558.4082376415505, + y: 123.72387429194112 }, version: '481', inputs: [ { key: 'userChatInput', - renderTypeList: ['reference', 'textarea'], - valueType: 'string', + renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea], + valueType: WorkflowIOValueTypeEnum.string, label: '用户问题', required: true, toolDescription: '用户问题' @@ -2118,882 +2222,944 @@ export const workflowTemplates: TemplateType = [ id: 'userChatInput', key: 'userChatInput', label: 'core.module.input.label.user question', - type: 'static', - valueType: 'string' + valueType: WorkflowIOValueTypeEnum.string, + type: FlowNodeOutputTypeEnum.static } ] }, { - nodeId: 'tMyUnRL5jIrC', - name: 'HTTP 请求', - intro: '可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)', - avatar: 'core/workflow/template/httpRequest', - flowNodeType: 'httpRequest468', + nodeId: '7BdojPlukIQw', + name: 'AI 对话', + intro: 'AI 大模型对话', + avatar: 'core/workflow/template/aiChat', + flowNodeType: FlowNodeTypeEnum.chatNode, showStatus: true, position: { - x: 931.6784209157559, - y: -162.36850541742047 + x: 2701.1267277679685, + y: -767.8956312653042 }, - version: '486', + version: '481', inputs: [ { - key: 'system_addInputParam', - renderTypeList: ['addInputParam'], - valueType: 'dynamic', - label: '', - required: false, - description: 'core.module.input.description.HTTP Dynamic Input', - editField: { - key: true, - valueType: true - }, - customInputConfig: { - selectValueTypeList: [ - 'string', - 'number', - 'boolean', - 'object', - 'arrayString', - 'arrayNumber', - 'arrayBoolean', - 'arrayObject', - 'any', - 'chatHistory', - 'datasetQuote', - 'dynamic', - 'selectApp', - 'selectDataset' - ], - showDescription: false, - showDefaultValue: true - } + key: 'model', + renderTypeList: [ + FlowNodeInputTypeEnum.settingLLMModel, + FlowNodeInputTypeEnum.reference + ], + label: 'core.module.input.label.aiModel', + valueType: WorkflowIOValueTypeEnum.string, + value: 'gpt-4o-mini' }, { - key: 'system_httpMethod', - renderTypeList: ['custom'], - valueType: 'string', + key: 'temperature', + renderTypeList: [FlowNodeInputTypeEnum.hidden], label: '', - value: 'POST', - required: true + value: 3, + valueType: WorkflowIOValueTypeEnum.number, + min: 0, + max: 10, + step: 1 }, { - key: 'system_httpReqUrl', - renderTypeList: ['hidden'], - valueType: 'string', + key: 'maxToken', + renderTypeList: [FlowNodeInputTypeEnum.hidden], label: '', - description: 'core.module.input.description.Http Request Url', - placeholder: 'https://api.ai.com/getInventory', - required: false, - value: 'https://api.openai.com/v1/images/generations' + value: 1950, + valueType: WorkflowIOValueTypeEnum.number, + min: 100, + max: 4000, + step: 50 }, { - key: 'system_httpHeader', - renderTypeList: ['custom'], - valueType: 'any', - value: [ - { - key: 'Authorization', - type: 'string', - value: 'Bearer ' - } - ], + key: 'isResponseAnswerText', + renderTypeList: [FlowNodeInputTypeEnum.hidden], label: '', - description: 'core.module.input.description.Http Request Header', - placeholder: 'core.module.input.description.Http Request Header', - required: false + value: true, + valueType: WorkflowIOValueTypeEnum.boolean }, { - key: 'system_httpParams', - renderTypeList: ['hidden'], - valueType: 'any', - value: [], + key: 'quoteTemplate', + renderTypeList: [FlowNodeInputTypeEnum.hidden], label: '', - required: false + valueType: WorkflowIOValueTypeEnum.string }, { - key: 'system_httpJsonBody', - renderTypeList: ['hidden'], - valueType: 'any', - value: - '{\n "model": "dall-e-3",\n "prompt": "{{prompt}}",\n "n": 1,\n "size": "1024x1024"\n}', + key: 'quotePrompt', + renderTypeList: [FlowNodeInputTypeEnum.hidden], label: '', - required: false + valueType: WorkflowIOValueTypeEnum.string }, { - key: 'prompt', - valueType: 'string', - label: 'prompt', - renderTypeList: ['reference'], + key: 'systemPrompt', + renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference], + max: 3000, + valueType: WorkflowIOValueTypeEnum.string, + label: 'core.ai.Prompt', + description: 'core.app.tip.chatNodeSystemPromptTip', + placeholder: 'core.app.tip.chatNodeSystemPromptTip', + value: '' + }, + { + key: 'history', + renderTypeList: [FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.reference], + valueType: WorkflowIOValueTypeEnum.chatHistory, + label: 'core.module.input.label.chat history', + required: true, + min: 0, + max: 30, + value: 6 + }, + { + key: 'userChatInput', + renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea], + valueType: WorkflowIOValueTypeEnum.string, + label: '用户问题', + required: true, + toolDescription: '用户问题', + value: ['workflowStartNodeId', 'userChatInput'] + }, + { + key: 'quoteQA', + renderTypeList: [FlowNodeInputTypeEnum.settingDatasetQuotePrompt], + label: '', + debugLabel: '知识库引用', description: '', - canEdit: true, - editField: { - key: true, - valueType: true - }, - value: ['448745', 'userChatInput'] + valueType: WorkflowIOValueTypeEnum.datasetQuote, + value: ['MNMMMIjjWyMU', 'quoteQA'] } ], outputs: [ { - id: 'system_addOutputParam', - key: 'system_addOutputParam', - type: 'dynamic', - valueType: 'dynamic', - label: '', - customFieldConfig: { - selectValueTypeList: [ - 'string', - 'number', - 'boolean', - 'object', - 'arrayString', - 'arrayNumber', - 'arrayBoolean', - 'arrayObject', - 'any', - 'chatHistory', - 'datasetQuote', - 'dynamic', - 'selectApp', - 'selectDataset' - ], - showDescription: false, - showDefaultValue: true - } + id: 'history', + key: 'history', + label: 'core.module.output.label.New context', + description: 'core.module.output.description.New context', + valueType: WorkflowIOValueTypeEnum.chatHistory, + type: FlowNodeOutputTypeEnum.static }, { - id: 'error', - key: 'error', - label: '请求错误', - description: 'HTTP请求错误信息,成功时返回空', - valueType: 'object', - type: 'static' + id: 'answerText', + key: 'answerText', + label: 'core.module.output.label.Ai response content', + description: 'core.module.output.description.Ai response content', + valueType: WorkflowIOValueTypeEnum.string, + type: FlowNodeOutputTypeEnum.static + } + ] + }, + { + nodeId: 'rvbo634w3AYj', + name: '问题分类', + intro: + '根据用户的历史记录和当前问题判断该次提问的类型。可以添加多组问题类型,下面是一个模板例子:\n类型1: 打招呼\n类型2: 关于商品“使用”问题\n类型3: 关于商品“购买”问题\n类型4: 其他问题', + avatar: 'core/workflow/template/questionClassify', + flowNodeType: FlowNodeTypeEnum.classifyQuestion, + showStatus: true, + position: { + x: 1020.9667229609946, + y: -385.0060974413916 + }, + version: '481', + inputs: [ + { + key: 'model', + renderTypeList: [FlowNodeInputTypeEnum.selectLLMModel, FlowNodeInputTypeEnum.reference], + label: 'core.module.input.label.aiModel', + required: true, + valueType: WorkflowIOValueTypeEnum.string, + llmModelType: 'classify', + value: 'gpt-4o-mini' }, { - id: 'httpRawResponse', - key: 'httpRawResponse', - label: '原始响应', + key: 'systemPrompt', + renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference], + max: 3000, + valueType: WorkflowIOValueTypeEnum.string, + label: 'core.module.input.label.Background', + description: 'core.module.input.description.Background', + placeholder: 'core.module.input.placeholder.Classify background', + value: '' + }, + { + key: 'history', + renderTypeList: [FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.reference], + valueType: WorkflowIOValueTypeEnum.chatHistory, + label: 'core.module.input.label.chat history', required: true, - description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。', - valueType: 'any', - type: 'static' + min: 0, + max: 30, + value: 6 }, { - id: 'DeKGGioBwaMf', - type: 'dynamic', - key: 'data[0].url', - valueType: 'string', - label: 'data[0].url' + key: 'userChatInput', + renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea], + valueType: WorkflowIOValueTypeEnum.string, + label: '用户问题', + required: true, + value: ['workflowStartNodeId', 'userChatInput'] + }, + { + key: 'agents', + renderTypeList: [FlowNodeInputTypeEnum.custom], + valueType: WorkflowIOValueTypeEnum.any, + label: '', + value: [ + { + value: '关于电影《星际穿越》的问题', + key: 'wqre' + }, + { + value: '打招呼、问候等问题', + key: 'sdfa' + }, + { + value: '其他问题', + key: 'agex' + } + ] + } + ], + outputs: [ + { + id: 'cqResult', + key: 'cqResult', + label: '分类结果', + valueType: WorkflowIOValueTypeEnum.string, + type: FlowNodeOutputTypeEnum.static } ] }, { - nodeId: '7mapnCgHfKW6', + nodeId: '7kwgL1dVlwG6', name: '指定回复', intro: '该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。', avatar: 'core/workflow/template/reply', - flowNodeType: 'answerNode', + flowNodeType: FlowNodeTypeEnum.answerNode, position: { - x: 2204.4609372615846, - y: 163.11883652393863 + x: 1874.9167551056487, + y: 434.98431875888207 }, version: '481', inputs: [ { key: 'text', - renderTypeList: ['textarea', 'reference'], - valueType: 'any', + renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference], + valueType: WorkflowIOValueTypeEnum.string, label: 'core.module.input.label.Response content', description: 'core.module.input.description.Response content', placeholder: 'core.module.input.description.Response content', selectedTypeIndex: 1, - value: ['vEXJF8pQ8eOv', 'system_text'], - required: true + value: ['rvbo634w3AYj', 'cqResult'] } ], outputs: [] }, { - nodeId: 'vEXJF8pQ8eOv', - name: '文本拼接', - intro: '可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。', - avatar: 'core/workflow/template/textConcat', - flowNodeType: 'textEditor', + nodeId: 'MNMMMIjjWyMU', + name: '知识库搜索', + intro: '调用“语义检索”和“全文检索”能力,从“知识库”中查找可能与问题相关的参考内容', + avatar: 'core/workflow/template/datasetSearch', + flowNodeType: FlowNodeTypeEnum.datasetSearchNode, + showStatus: true, position: { - x: 1544.8821308368042, - y: -27.22950739442814 + x: 1851.010152279949, + y: -613.3555232387284 }, - version: '486', + version: '481', inputs: [ { - key: 'system_addInputParam', - renderTypeList: ['addInputParam'], - valueType: 'dynamic', + key: 'datasets', + renderTypeList: [FlowNodeInputTypeEnum.selectDataset, FlowNodeInputTypeEnum.reference], + label: 'core.module.input.label.Select dataset', + value: [], + valueType: WorkflowIOValueTypeEnum.selectDataset, + list: [], + required: true + }, + { + key: 'similarity', + renderTypeList: [FlowNodeInputTypeEnum.selectDatasetParamsModal], label: '', - required: false, - description: '可以引用其他节点的输出,作为文本拼接的变量,通过 {{字段名}} 来引用变量', - customInputConfig: { - selectValueTypeList: [ - 'string', - 'number', - 'boolean', - 'object', - 'arrayString', - 'arrayNumber', - 'arrayBoolean', - 'arrayObject', - 'any', - 'chatHistory', - 'datasetQuote', - 'dynamic', - 'selectApp', - 'selectDataset' - ], - showDescription: false, - showDefaultValue: false - } + value: 0.4, + valueType: WorkflowIOValueTypeEnum.number }, { - key: 'system_textareaInput', - renderTypeList: ['textarea'], - valueType: 'string', - required: true, - label: '拼接文本', - placeholder: '可通过 {{字段名}} 来引用变量', - value: '![]({{url}})' + key: 'limit', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + label: '', + value: 1500, + valueType: WorkflowIOValueTypeEnum.number }, { - renderTypeList: ['reference'], - valueType: 'string', - canEdit: true, - key: 'url', - label: 'url', - customInputConfig: { - selectValueTypeList: [ - 'string', - 'number', - 'boolean', - 'object', - 'arrayString', - 'arrayNumber', - 'arrayBoolean', - 'arrayObject', - 'any', - 'chatHistory', - 'datasetQuote', - 'dynamic', - 'selectApp', - 'selectDataset' - ], - showDescription: false, - showDefaultValue: false - }, + key: 'searchMode', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + label: '', + valueType: WorkflowIOValueTypeEnum.string, + value: 'embedding' + }, + { + key: 'usingReRank', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + label: '', + valueType: WorkflowIOValueTypeEnum.boolean, + value: false + }, + { + key: 'datasetSearchUsingExtensionQuery', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + label: '', + valueType: WorkflowIOValueTypeEnum.boolean, + value: true + }, + { + key: 'datasetSearchExtensionModel', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + label: '', + valueType: WorkflowIOValueTypeEnum.string + }, + { + key: 'datasetSearchExtensionBg', + renderTypeList: [FlowNodeInputTypeEnum.hidden], + label: '', + valueType: WorkflowIOValueTypeEnum.string, + value: '' + }, + { + key: 'userChatInput', + renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea], + valueType: WorkflowIOValueTypeEnum.string, + label: '用户问题', required: true, - value: ['tMyUnRL5jIrC', 'DeKGGioBwaMf'] + toolDescription: '需要检索的内容', + value: ['workflowStartNodeId', 'userChatInput'] } ], outputs: [ { - id: 'system_text', - key: 'system_text', - label: '拼接结果', - type: 'static', - valueType: 'string' + id: 'quoteQA', + key: 'quoteQA', + label: 'core.module.Dataset quote.label', + description: '特殊数组格式,搜索结果为空时,返回空数组。', + type: FlowNodeOutputTypeEnum.static, + valueType: WorkflowIOValueTypeEnum.datasetQuote } ] } ], edges: [ { - source: '448745', - target: 'tMyUnRL5jIrC', - sourceHandle: '448745-source-right', - targetHandle: 'tMyUnRL5jIrC-target-left' + source: 'workflowStartNodeId', + target: 'rvbo634w3AYj', + sourceHandle: 'workflowStartNodeId-source-right', + targetHandle: 'rvbo634w3AYj-target-left' + }, + { + source: 'rvbo634w3AYj', + target: '7kwgL1dVlwG6', + sourceHandle: 'rvbo634w3AYj-source-agex', + targetHandle: '7kwgL1dVlwG6-target-left' + }, + { + source: 'rvbo634w3AYj', + target: 'MNMMMIjjWyMU', + sourceHandle: 'rvbo634w3AYj-source-wqre', + targetHandle: 'MNMMMIjjWyMU-target-left' }, { - source: 'tMyUnRL5jIrC', - target: 'vEXJF8pQ8eOv', - sourceHandle: 'tMyUnRL5jIrC-source-right', - targetHandle: 'vEXJF8pQ8eOv-target-left' + source: 'MNMMMIjjWyMU', + target: '7BdojPlukIQw', + sourceHandle: 'MNMMMIjjWyMU-source-right', + targetHandle: '7BdojPlukIQw-target-left' }, { - source: 'vEXJF8pQ8eOv', - target: '7mapnCgHfKW6', - sourceHandle: 'vEXJF8pQ8eOv-source-right', - targetHandle: '7mapnCgHfKW6-target-left' + source: 'rvbo634w3AYj', + target: '7kwgL1dVlwG6', + sourceHandle: 'rvbo634w3AYj-source-sdfa', + targetHandle: '7kwgL1dVlwG6-target-left' } ] - }, + } +]; + +export const pluginTemplates: TemplateType = [ { - id: 'CQ', - avatar: 'core/workflow/template/questionClassify', - name: '问题分类 + 知识库', - intro: '先对用户的问题进行分类,再根据不同类型问题,执行不同的操作', - type: AppTypeEnum.workflow, + id: 'plugin-simple', + avatar: 'core/workflow/template/aiChat', + name: '默认模板', + intro: '标准的插件初始模板', + type: AppTypeEnum.plugin, modules: [ { - nodeId: 'userGuide', - name: '系统配置', - intro: '可以配置应用的系统参数', - avatar: 'core/workflow/template/systemConfig', - flowNodeType: FlowNodeTypeEnum.systemConfig, + nodeId: 'pluginInput', + name: '自定义插件输入', + avatar: 'core/workflow/template/workflowStart', + flowNodeType: FlowNodeTypeEnum.pluginInput, + showStatus: false, position: { - x: 531.2422736065552, - y: -486.7611729549753 + x: 616.4226348688949, + y: -165.05298493910115 }, version: '481', - inputs: [ - { - key: 'welcomeText', - renderTypeList: [FlowNodeInputTypeEnum.hidden], - valueType: WorkflowIOValueTypeEnum.string, - label: 'core.app.Welcome Text', - value: '你好,我是知识库助手,请不要忘记选择知识库噢~\n[你是谁]\n[如何使用]' - }, - { - key: 'variables', - renderTypeList: [FlowNodeInputTypeEnum.hidden], - valueType: WorkflowIOValueTypeEnum.any, - label: 'core.app.Chat Variable', - value: [] - }, - { - key: 'questionGuide', - valueType: WorkflowIOValueTypeEnum.boolean, - renderTypeList: [FlowNodeInputTypeEnum.hidden], - label: 'core.app.Question Guide', - value: true - }, - { - key: 'tts', - renderTypeList: [FlowNodeInputTypeEnum.hidden], - valueType: WorkflowIOValueTypeEnum.any, - label: '', - value: { - type: 'web' - } - }, - { - key: 'whisper', - renderTypeList: [FlowNodeInputTypeEnum.hidden], - valueType: WorkflowIOValueTypeEnum.any, - label: '', - value: { - open: false, - autoSend: false, - autoTTSResponse: false - } - }, - { - key: 'scheduleTrigger', - renderTypeList: [FlowNodeInputTypeEnum.hidden], - valueType: WorkflowIOValueTypeEnum.any, - label: '', - value: null - } - ], + inputs: [], outputs: [] }, { - nodeId: 'workflowStartNodeId', - name: '流程开始', - intro: '', + nodeId: 'pluginOutput', + name: '自定义插件输出', + avatar: '/imgs/workflow/output.png', + flowNodeType: FlowNodeTypeEnum.pluginOutput, + showStatus: false, + position: { + x: 1607.7142331269126, + y: -151.8669210746189 + }, + version: '481', + inputs: [], + outputs: [] + } + ], + edges: [] + }, + { + id: 'plugin-feishu', + avatar: '/imgs/app/templates/feishu.svg', + name: '飞书webhook插件', + intro: '通过 webhook 给飞书机器人发送一条消息', + type: AppTypeEnum.plugin, + modules: [ + { + nodeId: 'pluginInput', + name: '自定义插件输入', + intro: '自定义配置外部输入,使用插件时,仅暴露自定义配置的输入', avatar: 'core/workflow/template/workflowStart', - flowNodeType: FlowNodeTypeEnum.workflowStart, + flowNodeType: 'pluginInput', + showStatus: false, position: { - x: 558.4082376415505, - y: 123.72387429194112 + x: 517.5620777851774, + y: -173.55711888178655 }, version: '481', inputs: [ { - key: 'userChatInput', - renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea], - valueType: WorkflowIOValueTypeEnum.string, - label: '用户问题', + inputType: 'input', + valueType: 'string', + key: '飞书机器人地址', + label: '飞书机器人地址', + description: '', + isToolInput: false, + defaultValue: '', + editField: { + key: true + }, + dynamicParamDefaultValue: { + inputType: 'reference', + valueType: 'string', + required: true + }, + renderTypeList: ['input'], required: true, - toolDescription: '用户问题' + canEdit: true, + value: '' + }, + { + key: '发送的消息', + valueType: 'string', + label: '发送的消息', + renderTypeList: ['reference'], + required: true, + description: '', + canEdit: true, + value: '', + editField: { + key: true + }, + dynamicParamDefaultValue: { + inputType: 'reference', + valueType: 'string', + required: true + } } ], outputs: [ { - id: 'userChatInput', - key: 'userChatInput', - label: 'core.module.input.label.user question', - valueType: WorkflowIOValueTypeEnum.string, - type: FlowNodeOutputTypeEnum.static + id: 'mv52BrPVE6bm', + key: '飞书机器人地址', + valueType: 'string', + label: '飞书机器人地址', + type: 'static' + }, + { + id: 'p0m68Dv5KaIp', + key: '发送的消息', + valueType: 'string', + label: '发送的消息', + type: 'static' } ] }, { - nodeId: '7BdojPlukIQw', - name: 'AI 对话', - intro: 'AI 大模型对话', - avatar: 'core/workflow/template/aiChat', - flowNodeType: FlowNodeTypeEnum.chatNode, - showStatus: true, + nodeId: 'pluginOutput', + name: '自定义插件输出', + intro: '自定义配置外部输出,使用插件时,仅暴露自定义配置的输出', + avatar: '/imgs/workflow/output.png', + flowNodeType: 'pluginOutput', + showStatus: false, position: { - x: 2701.1267277679685, - y: -767.8956312653042 + x: 1668.9410524554828, + y: -153.47815316221283 }, version: '481', - inputs: [ - { - key: 'model', - renderTypeList: [ - FlowNodeInputTypeEnum.settingLLMModel, - FlowNodeInputTypeEnum.reference - ], - label: 'core.module.input.label.aiModel', - valueType: WorkflowIOValueTypeEnum.string, - value: 'gpt-4o-mini' - }, - { - key: 'temperature', - renderTypeList: [FlowNodeInputTypeEnum.hidden], - label: '', - value: 3, - valueType: WorkflowIOValueTypeEnum.number, - min: 0, - max: 10, - step: 1 - }, + inputs: [], + outputs: [] + }, + { + nodeId: 'rKBYGQuYefae', + name: 'HTTP 请求', + intro: '可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)', + avatar: 'core/workflow/template/httpRequest', + flowNodeType: 'httpRequest468', + showStatus: true, + position: { + x: 1069.7228495148624, + y: -392.26482361861054 + }, + version: '481', + inputs: [ { - key: 'maxToken', - renderTypeList: [FlowNodeInputTypeEnum.hidden], + key: 'system_addInputParam', + renderTypeList: ['addInputParam'], + valueType: 'dynamic', label: '', - value: 1950, - valueType: WorkflowIOValueTypeEnum.number, - min: 100, - max: 4000, - step: 50 + required: false, + description: 'core.module.input.description.HTTP Dynamic Input' }, { - key: 'isResponseAnswerText', - renderTypeList: [FlowNodeInputTypeEnum.hidden], - label: '', - value: true, - valueType: WorkflowIOValueTypeEnum.boolean + key: 'text', + valueType: 'string', + label: 'text', + renderTypeList: ['reference'], + description: '', + canEdit: true, + editField: { + key: true, + valueType: true + }, + value: ['pluginInput', 'p0m68Dv5KaIp'] }, { - key: 'quoteTemplate', - renderTypeList: [FlowNodeInputTypeEnum.hidden], - label: '', - valueType: WorkflowIOValueTypeEnum.string + key: 'url', + valueType: 'string', + label: 'url', + renderTypeList: ['reference'], + description: '', + canEdit: true, + editField: { + key: true, + valueType: true + }, + value: ['pluginInput', 'mv52BrPVE6bm'] }, { - key: 'quotePrompt', - renderTypeList: [FlowNodeInputTypeEnum.hidden], + key: 'system_httpMethod', + renderTypeList: ['custom'], + valueType: 'string', label: '', - valueType: WorkflowIOValueTypeEnum.string + value: 'POST', + required: true }, { - key: 'systemPrompt', - renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference], - max: 3000, - valueType: WorkflowIOValueTypeEnum.string, - label: 'core.ai.Prompt', - description: 'core.app.tip.chatNodeSystemPromptTip', - placeholder: 'core.app.tip.chatNodeSystemPromptTip', - value: '' + key: 'system_httpReqUrl', + renderTypeList: ['hidden'], + valueType: 'string', + label: '', + description: 'core.module.input.description.Http Request Url', + placeholder: 'https://api.ai.com/getInventory', + required: false, + value: '{{url}}' }, { - key: 'history', - renderTypeList: [FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.reference], - valueType: WorkflowIOValueTypeEnum.chatHistory, - label: 'core.module.input.label.chat history', - required: true, - min: 0, - max: 30, - value: 6 + key: 'system_httpHeader', + renderTypeList: ['custom'], + valueType: 'any', + value: [], + label: '', + description: 'core.module.input.description.Http Request Header', + placeholder: 'core.module.input.description.Http Request Header', + required: false }, { - key: 'userChatInput', - renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea], - valueType: WorkflowIOValueTypeEnum.string, - label: '用户问题', - required: true, - toolDescription: '用户问题', - value: ['workflowStartNodeId', 'userChatInput'] + key: 'system_httpParams', + renderTypeList: ['hidden'], + valueType: 'any', + value: [], + label: '', + required: false }, { - key: 'quoteQA', - renderTypeList: [FlowNodeInputTypeEnum.settingDatasetQuotePrompt], + key: 'system_httpJsonBody', + renderTypeList: ['hidden'], + valueType: 'any', + value: + '{\r\n "msg_type": "text",\r\n "content": {\r\n "text": "{{text}}"\r\n }\r\n}', label: '', - debugLabel: '知识库引用', - description: '', - valueType: WorkflowIOValueTypeEnum.datasetQuote, - value: ['MNMMMIjjWyMU', 'quoteQA'] + required: false } ], outputs: [ { - id: 'history', - key: 'history', - label: 'core.module.output.label.New context', - description: 'core.module.output.description.New context', - valueType: WorkflowIOValueTypeEnum.chatHistory, - type: FlowNodeOutputTypeEnum.static + id: 'system_addOutputParam', + key: 'system_addOutputParam', + type: 'dynamic', + valueType: 'dynamic', + label: '', + editField: { + key: true, + valueType: true + } }, { - id: 'answerText', - key: 'answerText', - label: 'core.module.output.label.Ai response content', - description: 'core.module.output.description.Ai response content', - valueType: WorkflowIOValueTypeEnum.string, - type: FlowNodeOutputTypeEnum.static + id: 'error', + key: 'error', + label: '请求错误', + description: 'HTTP请求错误信息,成功时返回空', + valueType: 'object', + type: 'static' + }, + { + id: 'httpRawResponse', + key: 'httpRawResponse', + label: '原始响应', + required: true, + description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。', + valueType: 'any', + type: 'static' } ] + } + ], + edges: [ + { + source: 'pluginInput', + target: 'rKBYGQuYefae', + sourceHandle: 'pluginInput-source-right', + targetHandle: 'rKBYGQuYefae-target-left' }, { - nodeId: 'rvbo634w3AYj', - name: '问题分类', - intro: - '根据用户的历史记录和当前问题判断该次提问的类型。可以添加多组问题类型,下面是一个模板例子:\n类型1: 打招呼\n类型2: 关于商品“使用”问题\n类型3: 关于商品“购买”问题\n类型4: 其他问题', - avatar: 'core/workflow/template/questionClassify', - flowNodeType: FlowNodeTypeEnum.classifyQuestion, - showStatus: true, + source: 'rKBYGQuYefae', + target: 'pluginOutput', + sourceHandle: 'rKBYGQuYefae-source-right', + targetHandle: 'pluginOutput-target-left' + } + ] + }, + { + id: 'dalle', + avatar: '/imgs/model/openai.svg', + name: 'Dalle3绘图', + intro: '通过请求Dalle3接口绘图,需要有 api key', + type: AppTypeEnum.plugin, + modules: [ + { + nodeId: 'pluginInput', + name: '自定义插件输入', + intro: '可以配置插件需要哪些输入,利用这些输入来运行插件', + avatar: 'core/workflow/template/workflowStart', + flowNodeType: 'pluginInput', + showStatus: false, position: { - x: 1020.9667229609946, - y: -385.0060974413916 + x: 412.7756423516722, + y: -99.80686112290361 }, version: '481', inputs: [ { - key: 'model', - renderTypeList: [FlowNodeInputTypeEnum.selectLLMModel, FlowNodeInputTypeEnum.reference], - label: 'core.module.input.label.aiModel', - required: true, - valueType: WorkflowIOValueTypeEnum.string, - llmModelType: 'classify', - value: 'gpt-4o-mini' - }, - { - key: 'systemPrompt', - renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference], - max: 3000, - valueType: WorkflowIOValueTypeEnum.string, - label: 'core.module.input.label.Background', - description: 'core.module.input.description.Background', - placeholder: 'core.module.input.placeholder.Classify background', - value: '' - }, - { - key: 'history', - renderTypeList: [FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.reference], - valueType: WorkflowIOValueTypeEnum.chatHistory, - label: 'core.module.input.label.chat history', - required: true, - min: 0, - max: 30, - value: 6 - }, - { - key: 'userChatInput', - renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea], - valueType: WorkflowIOValueTypeEnum.string, - label: '用户问题', + renderTypeList: ['reference'], + selectedTypeIndex: 0, + valueType: 'string', + canEdit: true, + key: '绘图提示词', + label: '绘图提示词', + description: '绘图提示词', required: true, - value: ['workflowStartNodeId', 'userChatInput'] - }, - { - key: 'agents', - renderTypeList: [FlowNodeInputTypeEnum.custom], - valueType: WorkflowIOValueTypeEnum.any, - label: '', - value: [ - { - value: '关于电影《星际穿越》的问题', - key: 'wqre' - }, - { - value: '打招呼、问候等问题', - key: 'sdfa' - }, - { - value: '其他问题', - key: 'agex' - } - ] + toolDescription: '绘图提示词' } ], outputs: [ { - id: 'cqResult', - key: 'cqResult', - label: '分类结果', - valueType: WorkflowIOValueTypeEnum.string, - type: FlowNodeOutputTypeEnum.static - } - ] - }, - { - nodeId: '7kwgL1dVlwG6', - name: '指定回复', - intro: - '该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。', - avatar: 'core/workflow/template/reply', - flowNodeType: FlowNodeTypeEnum.answerNode, + id: '绘图提示词', + valueType: 'string', + key: '绘图提示词', + label: '绘图提示词', + type: 'hidden' + } + ] + }, + { + nodeId: 'pluginOutput', + name: '自定义插件输出', + intro: '自定义配置外部输出,使用插件时,仅暴露自定义配置的输出', + avatar: 'core/workflow/template/pluginOutput', + flowNodeType: 'pluginOutput', + showStatus: false, position: { - x: 1874.9167551056487, - y: 434.98431875888207 + x: 1822.7195641525896, + y: -193.54601587659562 }, version: '481', inputs: [ { - key: 'text', - renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference], - valueType: WorkflowIOValueTypeEnum.string, - label: 'core.module.input.label.Response content', - description: 'core.module.input.description.Response content', - placeholder: 'core.module.input.description.Response content', - selectedTypeIndex: 1, - value: ['rvbo634w3AYj', 'cqResult'] + renderTypeList: ['reference'], + valueType: 'string', + canEdit: true, + key: '图片访问链接', + label: '图片访问链接', + description: '', + value: ['tMvel910bnrJ', 'pJXgWoTpPoMy'] + }, + { + renderTypeList: ['reference'], + valueType: 'object', + canEdit: true, + key: 'error', + label: '错误信息', + description: '', + value: ['tMvel910bnrJ', 'error'] } ], outputs: [] }, { - nodeId: 'MNMMMIjjWyMU', - name: '知识库搜索', - intro: '调用“语义检索”和“全文检索”能力,从“知识库”中查找可能与问题相关的参考内容', - avatar: 'core/workflow/template/datasetSearch', - flowNodeType: FlowNodeTypeEnum.datasetSearchNode, + nodeId: 'tMvel910bnrJ', + name: 'HTTP 请求', + intro: '可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)', + avatar: 'core/workflow/template/httpRequest', + flowNodeType: 'httpRequest468', showStatus: true, position: { - x: 1851.010152279949, - y: -613.3555232387284 + x: 1044.8838211811253, + y: -414.7785530936485 }, version: '481', inputs: [ { - key: 'datasets', - renderTypeList: [FlowNodeInputTypeEnum.selectDataset, FlowNodeInputTypeEnum.reference], - label: 'core.module.input.label.Select dataset', - value: [], - valueType: WorkflowIOValueTypeEnum.selectDataset, - list: [], - required: true - }, - { - key: 'similarity', - renderTypeList: [FlowNodeInputTypeEnum.selectDatasetParamsModal], - label: '', - value: 0.4, - valueType: WorkflowIOValueTypeEnum.number - }, - { - key: 'limit', - renderTypeList: [FlowNodeInputTypeEnum.hidden], + key: 'system_addInputParam', + renderTypeList: ['addInputParam'], + valueType: 'dynamic', label: '', - value: 1500, - valueType: WorkflowIOValueTypeEnum.number + required: false, + description: 'core.module.input.description.HTTP Dynamic Input', + customInputConfig: { + selectValueTypeList: [ + 'string', + 'number', + 'boolean', + 'object', + 'arrayString', + 'arrayNumber', + 'arrayBoolean', + 'arrayObject', + 'any', + 'chatHistory', + 'datasetQuote', + 'dynamic', + 'selectApp', + 'selectDataset' + ], + showDescription: false, + showDefaultValue: true + } }, { - key: 'searchMode', - renderTypeList: [FlowNodeInputTypeEnum.hidden], + key: 'system_httpMethod', + renderTypeList: ['custom'], + valueType: 'string', label: '', - valueType: WorkflowIOValueTypeEnum.string, - value: 'embedding' + value: 'POST', + required: true }, { - key: 'usingReRank', - renderTypeList: [FlowNodeInputTypeEnum.hidden], + key: 'system_httpReqUrl', + renderTypeList: ['hidden'], + valueType: 'string', label: '', - valueType: WorkflowIOValueTypeEnum.boolean, - value: false + description: 'core.module.input.description.Http Request Url', + placeholder: 'https://api.ai.com/getInventory', + required: false, + value: '{{url}}/v1/images/generations' }, { - key: 'datasetSearchUsingExtensionQuery', - renderTypeList: [FlowNodeInputTypeEnum.hidden], + key: 'system_httpHeader', + renderTypeList: ['custom'], + valueType: 'any', + value: [ + { + key: 'Authorization', + type: 'string', + value: 'Bearer {{authorization}}' + } + ], label: '', - valueType: WorkflowIOValueTypeEnum.boolean, - value: true + description: 'core.module.input.description.Http Request Header', + placeholder: 'core.module.input.description.Http Request Header', + required: false }, { - key: 'datasetSearchExtensionModel', - renderTypeList: [FlowNodeInputTypeEnum.hidden], + key: 'system_httpParams', + renderTypeList: ['hidden'], + valueType: 'any', + value: [], label: '', - valueType: WorkflowIOValueTypeEnum.string + required: false }, { - key: 'datasetSearchExtensionBg', - renderTypeList: [FlowNodeInputTypeEnum.hidden], + key: 'system_httpJsonBody', + renderTypeList: ['hidden'], + valueType: 'any', + value: + '{\n "model": "dall-e-3",\n "prompt": "{{prompt}}",\n "n": 1,\n "size": "1024x1024"\n}', label: '', - valueType: WorkflowIOValueTypeEnum.string, - value: '' + required: false }, { - key: 'userChatInput', - renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea], - valueType: WorkflowIOValueTypeEnum.string, - label: '用户问题', + renderTypeList: ['reference'], + valueType: 'string', + canEdit: true, + key: 'prompt', + label: 'prompt', + customInputConfig: { + selectValueTypeList: [ + 'string', + 'number', + 'boolean', + 'object', + 'arrayString', + 'arrayNumber', + 'arrayBoolean', + 'arrayObject', + 'any', + 'chatHistory', + 'datasetQuote', + 'dynamic', + 'selectApp', + 'selectDataset' + ], + showDescription: false, + showDefaultValue: true + }, required: true, - toolDescription: '需要检索的内容', - value: ['workflowStartNodeId', 'userChatInput'] + value: ['pluginInput', '绘图提示词'] } ], outputs: [ { - id: 'quoteQA', - key: 'quoteQA', - label: 'core.module.Dataset quote.label', - description: '特殊数组格式,搜索结果为空时,返回空数组。', - type: FlowNodeOutputTypeEnum.static, - valueType: WorkflowIOValueTypeEnum.datasetQuote - } - ] - } - ], - edges: [ - { - source: 'workflowStartNodeId', - target: 'rvbo634w3AYj', - sourceHandle: 'workflowStartNodeId-source-right', - targetHandle: 'rvbo634w3AYj-target-left' - }, - { - source: 'rvbo634w3AYj', - target: '7kwgL1dVlwG6', - sourceHandle: 'rvbo634w3AYj-source-agex', - targetHandle: '7kwgL1dVlwG6-target-left' - }, - { - source: 'rvbo634w3AYj', - target: 'MNMMMIjjWyMU', - sourceHandle: 'rvbo634w3AYj-source-wqre', - targetHandle: 'MNMMMIjjWyMU-target-left' - }, - { - source: 'MNMMMIjjWyMU', - target: '7BdojPlukIQw', - sourceHandle: 'MNMMMIjjWyMU-source-right', - targetHandle: '7BdojPlukIQw-target-left' - }, - { - source: 'rvbo634w3AYj', - target: '7kwgL1dVlwG6', - sourceHandle: 'rvbo634w3AYj-source-sdfa', - targetHandle: '7kwgL1dVlwG6-target-left' + id: 'error', + key: 'error', + label: '请求错误', + description: 'HTTP请求错误信息,成功时返回空', + valueType: 'object', + type: 'static' + }, + { + id: 'httpRawResponse', + key: 'httpRawResponse', + label: '原始响应', + required: true, + description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。', + valueType: 'any', + type: 'static' + }, + { + id: 'system_addOutputParam', + key: 'system_addOutputParam', + type: 'dynamic', + valueType: 'dynamic', + label: '', + customFieldConfig: { + selectValueTypeList: [ + 'string', + 'number', + 'boolean', + 'object', + 'arrayString', + 'arrayNumber', + 'arrayBoolean', + 'arrayObject', + 'any', + 'chatHistory', + 'datasetQuote', + 'dynamic', + 'selectApp', + 'selectDataset' + ], + showDescription: false, + showDefaultValue: false + } + }, + { + id: 'pJXgWoTpPoMy', + valueType: 'string', + type: 'dynamic', + key: 'data[0].url', + label: 'data[0].url' + } + ] } - ] - } -]; - -export const pluginTemplates: TemplateType = [ - { - id: 'plugin-simple', - avatar: 'core/workflow/template/aiChat', - name: '默认模板', - intro: '标准的插件初始模板', - type: AppTypeEnum.plugin, - modules: [ + ], + edges: [ { - nodeId: 'pluginInput', - name: '自定义插件输入', - avatar: 'core/workflow/template/workflowStart', - flowNodeType: FlowNodeTypeEnum.pluginInput, - showStatus: false, - position: { - x: 616.4226348688949, - y: -165.05298493910115 - }, - version: '481', - inputs: [], - outputs: [] + source: 'pluginInput', + target: 'tMvel910bnrJ', + sourceHandle: 'pluginInput-source-right', + targetHandle: 'tMvel910bnrJ-target-left' }, { - nodeId: 'pluginOutput', - name: '自定义插件输出', - avatar: '/imgs/workflow/output.png', - flowNodeType: FlowNodeTypeEnum.pluginOutput, - showStatus: false, - position: { - x: 1607.7142331269126, - y: -151.8669210746189 - }, - version: '481', - inputs: [], - outputs: [] + source: 'tMvel910bnrJ', + target: 'pluginOutput', + sourceHandle: 'tMvel910bnrJ-source-right', + targetHandle: 'pluginOutput-target-left' } - ], - edges: [] + ] }, { - id: 'plugin-feishu', - avatar: '/imgs/app/templates/feishu.svg', - name: '飞书webhook插件', - intro: '通过 webhook 给飞书机器人发送一条消息', + id: 'flux', + avatar: '/imgs/app/templates/flux.svg', + name: 'Flux 绘图', + intro: '通过请求 Flux 接口绘图,需要有 api key', type: AppTypeEnum.plugin, modules: [ { nodeId: 'pluginInput', name: '自定义插件输入', - intro: '自定义配置外部输入,使用插件时,仅暴露自定义配置的输入', + intro: '可以配置插件需要哪些输入,利用这些输入来运行插件', avatar: 'core/workflow/template/workflowStart', flowNodeType: 'pluginInput', showStatus: false, position: { - x: 517.5620777851774, - y: -173.55711888178655 + x: 351.2046235980429, + y: -77.41739975794749 }, version: '481', inputs: [ { - inputType: 'input', + renderTypeList: ['reference'], + selectedTypeIndex: 0, valueType: 'string', - key: '飞书机器人地址', - label: '飞书机器人地址', - description: '', - isToolInput: false, - defaultValue: '', - editField: { - key: true - }, - dynamicParamDefaultValue: { - inputType: 'reference', - valueType: 'string', - required: true - }, - renderTypeList: ['input'], - required: true, canEdit: true, - value: '' - }, - { - key: '发送的消息', - valueType: 'string', - label: '发送的消息', - renderTypeList: ['reference'], + key: '绘图提示词', + label: '绘图提示词', + description: '绘图提示词', required: true, - description: '', - canEdit: true, - value: '', - editField: { - key: true - }, - dynamicParamDefaultValue: { - inputType: 'reference', - valueType: 'string', - required: true - } + toolDescription: '绘图提示词' } ], outputs: [ { - id: 'mv52BrPVE6bm', - key: '飞书机器人地址', - valueType: 'string', - label: '飞书机器人地址', - type: 'static' - }, - { - id: 'p0m68Dv5KaIp', - key: '发送的消息', + id: '绘图提示词', valueType: 'string', - label: '发送的消息', - type: 'static' + key: '绘图提示词', + label: '绘图提示词', + type: 'hidden' } ] }, @@ -3001,27 +3167,46 @@ export const pluginTemplates: TemplateType = [ nodeId: 'pluginOutput', name: '自定义插件输出', intro: '自定义配置外部输出,使用插件时,仅暴露自定义配置的输出', - avatar: '/imgs/workflow/output.png', + avatar: 'core/workflow/template/pluginOutput', flowNodeType: 'pluginOutput', showStatus: false, position: { - x: 1668.9410524554828, - y: -153.47815316221283 + x: 1983.6911708285384, + y: -95.86447885674228 }, version: '481', - inputs: [], + inputs: [ + { + renderTypeList: ['reference'], + valueType: 'string', + canEdit: true, + key: '图片访问链接', + label: '图片访问链接', + description: '', + value: ['tMvel910bnrJ', 'pJXgWoTpPoMy'] + }, + { + renderTypeList: ['reference'], + valueType: 'object', + canEdit: true, + key: 'error', + label: '错误信息', + description: '', + value: ['tMvel910bnrJ', 'error'] + } + ], outputs: [] }, { - nodeId: 'rKBYGQuYefae', + nodeId: 'tMvel910bnrJ', name: 'HTTP 请求', intro: '可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)', avatar: 'core/workflow/template/httpRequest', flowNodeType: 'httpRequest468', showStatus: true, position: { - x: 1069.7228495148624, - y: -392.26482361861054 + x: 1138.1732435351091, + y: -416.6443415407282 }, version: '481', inputs: [ @@ -3031,33 +3216,27 @@ export const pluginTemplates: TemplateType = [ valueType: 'dynamic', label: '', required: false, - description: 'core.module.input.description.HTTP Dynamic Input' - }, - { - key: 'text', - valueType: 'string', - label: 'text', - renderTypeList: ['reference'], - description: '', - canEdit: true, - editField: { - key: true, - valueType: true - }, - value: ['pluginInput', 'p0m68Dv5KaIp'] - }, - { - key: 'url', - valueType: 'string', - label: 'url', - renderTypeList: ['reference'], - description: '', - canEdit: true, - editField: { - key: true, - valueType: true - }, - value: ['pluginInput', 'mv52BrPVE6bm'] + description: 'core.module.input.description.HTTP Dynamic Input', + customInputConfig: { + selectValueTypeList: [ + 'string', + 'number', + 'boolean', + 'object', + 'arrayString', + 'arrayNumber', + 'arrayBoolean', + 'arrayObject', + 'any', + 'chatHistory', + 'datasetQuote', + 'dynamic', + 'selectApp', + 'selectDataset' + ], + showDescription: false, + showDefaultValue: true + } }, { key: 'system_httpMethod', @@ -3075,13 +3254,19 @@ export const pluginTemplates: TemplateType = [ description: 'core.module.input.description.Http Request Url', placeholder: 'https://api.ai.com/getInventory', required: false, - value: '{{url}}' + value: 'https://fal.run/fal-ai/flux-pro' }, { key: 'system_httpHeader', renderTypeList: ['custom'], valueType: 'any', - value: [], + value: [ + { + key: 'Authorization', + type: 'string', + value: 'Key {{apikey}}' + } + ], label: '', description: 'core.module.input.description.Http Request Header', placeholder: 'core.module.input.description.Http Request Header', @@ -3100,23 +3285,41 @@ export const pluginTemplates: TemplateType = [ renderTypeList: ['hidden'], valueType: 'any', value: - '{\r\n "msg_type": "text",\r\n "content": {\r\n "text": "{{text}}"\r\n }\r\n}', + '{\n "prompt": "{{prompt}}",\n "image_size": "landscape_4_3",\n "num_inference_steps": 28,\n "guidance_scale": 3.5\n}', label: '', required: false + }, + { + renderTypeList: ['reference'], + valueType: 'string', + canEdit: true, + key: 'prompt', + label: 'prompt', + customInputConfig: { + selectValueTypeList: [ + 'string', + 'number', + 'boolean', + 'object', + 'arrayString', + 'arrayNumber', + 'arrayBoolean', + 'arrayObject', + 'any', + 'chatHistory', + 'datasetQuote', + 'dynamic', + 'selectApp', + 'selectDataset' + ], + showDescription: false, + showDefaultValue: true + }, + required: true, + value: ['pluginInput', '绘图提示词'] } ], outputs: [ - { - id: 'system_addOutputParam', - key: 'system_addOutputParam', - type: 'dynamic', - valueType: 'dynamic', - label: '', - editField: { - key: true, - valueType: true - } - }, { id: 'error', key: 'error', @@ -3133,6 +3336,40 @@ export const pluginTemplates: TemplateType = [ description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。', valueType: 'any', type: 'static' + }, + { + id: 'system_addOutputParam', + key: 'system_addOutputParam', + type: 'dynamic', + valueType: 'dynamic', + label: '', + customFieldConfig: { + selectValueTypeList: [ + 'string', + 'number', + 'boolean', + 'object', + 'arrayString', + 'arrayNumber', + 'arrayBoolean', + 'arrayObject', + 'any', + 'chatHistory', + 'datasetQuote', + 'dynamic', + 'selectApp', + 'selectDataset' + ], + showDescription: false, + showDefaultValue: false + } + }, + { + id: 'pJXgWoTpPoMy', + valueType: 'string', + type: 'dynamic', + key: 'images[0].url', + label: 'images[0].url' } ] } @@ -3140,14 +3377,14 @@ export const pluginTemplates: TemplateType = [ edges: [ { source: 'pluginInput', - target: 'rKBYGQuYefae', + target: 'tMvel910bnrJ', sourceHandle: 'pluginInput-source-right', - targetHandle: 'rKBYGQuYefae-target-left' + targetHandle: 'tMvel910bnrJ-target-left' }, { - source: 'rKBYGQuYefae', + source: 'tMvel910bnrJ', target: 'pluginOutput', - sourceHandle: 'rKBYGQuYefae-source-right', + sourceHandle: 'tMvel910bnrJ-source-right', targetHandle: 'pluginOutput-target-left' } ] diff --git a/projects/app/src/web/core/chat/utils.ts b/projects/app/src/web/core/chat/utils.ts index a7ee8ddd39c..e33c38ed576 100644 --- a/projects/app/src/web/core/chat/utils.ts +++ b/projects/app/src/web/core/chat/utils.ts @@ -2,12 +2,11 @@ import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node.d'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; +import { getWebLLMModel } from '@/web/common/system/utils'; export function checkChatSupportSelectFileByChatModels(models: string[] = []) { - const llmModelList = useSystemStore.getState().llmModelList; - for (const model of models) { - const modelData = llmModelList.find((item) => item.model === model || item.name === model); + const modelData = getWebLLMModel(model); if (modelData?.vision) { return true; }