diff --git a/packages/global/core/chat/type.d.ts b/packages/global/core/chat/type.d.ts index 22d98dda8..ffc71fa89 100644 --- a/packages/global/core/chat/type.d.ts +++ b/packages/global/core/chat/type.d.ts @@ -155,6 +155,6 @@ export type ToolModuleResponseItemType = { /* dispatch run time */ export type RuntimeUserPromptType = { - files?: UserChatItemValueItemType['file'][]; + files: UserChatItemValueItemType['file'][]; text: string; }; diff --git a/packages/global/core/chat/utils.ts b/packages/global/core/chat/utils.ts index bd8c58c2a..75a858ee1 100644 --- a/packages/global/core/chat/utils.ts +++ b/packages/global/core/chat/utils.ts @@ -1,7 +1,7 @@ import { DispatchNodeResponseType } from '../workflow/runtime/type'; -import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '../workflow/node/constant'; +import { FlowNodeTypeEnum } from '../workflow/node/constant'; import { ChatItemValueTypeEnum, ChatRoleEnum } from './constants'; -import { ChatHistoryItemResType, ChatItemType } from './type.d'; +import { ChatHistoryItemResType, ChatItemType, UserChatItemValueItemType } from './type.d'; export const getChatTitleFromChatMessage = (message?: ChatItemType, defaultValue = '新对话') => { // @ts-ignore @@ -77,3 +77,15 @@ export const filterPublicNodeResponseData = ({ return obj as ChatHistoryItemResType; }); }; + +export const removeEmptyUserInput = (input: UserChatItemValueItemType[]) => { + return input.filter((item) => { + if (item.type === ChatItemValueTypeEnum.text && !item.text?.content?.trim()) { + return false; + } + if (item.type === ChatItemValueTypeEnum.file && !item.file?.url) { + return false; + } + return true; + }); +}; diff --git a/packages/global/core/workflow/constants.ts b/packages/global/core/workflow/constants.ts index f0677b046..7832142ce 100644 --- a/packages/global/core/workflow/constants.ts +++ b/packages/global/core/workflow/constants.ts @@ -37,7 +37,6 @@ export enum NodeInputKeyEnum { welcomeText = 'welcomeText', switch = 'switch', // a trigger switch history = 'history', - userChatInput = 'userChatInput', answerText = 'text', // system config @@ -47,6 +46,10 @@ export enum NodeInputKeyEnum { variables = 'variables', scheduleTrigger = 'scheduleTrigger', + // entry + userChatInput = 'userChatInput', + inputFiles = 'inputFiles', + agents = 'agents', // cq agent key // latest @@ -146,7 +149,7 @@ export enum VariableInputEnum { input = 'input', textarea = 'textarea', select = 'select', - external = 'external' + custom = 'custom' } export const variableMap = { [VariableInputEnum.input]: { @@ -164,10 +167,10 @@ export const variableMap = { title: 'core.module.variable.select type', desc: '' }, - [VariableInputEnum.external]: { + [VariableInputEnum.custom]: { icon: 'core/app/variable/external', - title: 'core.module.variable.External type', - desc: '可以通过API接口或分享链接的Query传递变量。增加该类型变量的主要目的是用于变量提示。使用例子: 你可以通过分享链接Query中拼接Token,来实现内部系统身份鉴权。' + title: 'core.module.variable.Custom type', + desc: '可以定义一个无需用户填写的全局变量。\n该变量的值可以来自于 API 接口,分享链接的 Query 或通过【变量更新】模块进行赋值。' } }; diff --git a/packages/global/core/workflow/runtime/utils.ts b/packages/global/core/workflow/runtime/utils.ts index 353981b61..e4e238ee1 100644 --- a/packages/global/core/workflow/runtime/utils.ts +++ b/packages/global/core/workflow/runtime/utils.ts @@ -5,6 +5,8 @@ import { StoreNodeItemType } from '../type'; import { StoreEdgeItemType } from '../type/edge'; import { RuntimeEdgeItemType, RuntimeNodeItemType } from './type'; import { VARIABLE_NODE_ID } from '../constants'; +import { isReferenceValue } from '../utils'; +import { ReferenceValueProps } from '../type/io'; export const initWorkflowEdgeStatus = (edges: StoreEdgeItemType[]): RuntimeEdgeItemType[] => { return ( @@ -138,16 +140,11 @@ export const getReferenceVariableValue = ({ nodes, variables }: { - value: [string, string]; + value: ReferenceValueProps; nodes: RuntimeNodeItemType[]; variables: Record; }) => { - if ( - !Array.isArray(value) || - value.length !== 2 || - typeof value[0] !== 'string' || - typeof value[1] !== 'string' - ) { + if (!isReferenceValue(value)) { return value; } const sourceNodeId = value[0]; diff --git a/packages/global/core/workflow/template/system/assignedAnswer.ts b/packages/global/core/workflow/template/system/assignedAnswer.ts index b8180a450..5ccb38ab3 100644 --- a/packages/global/core/workflow/template/system/assignedAnswer.ts +++ b/packages/global/core/workflow/template/system/assignedAnswer.ts @@ -1,14 +1,9 @@ -import { - FlowNodeInputTypeEnum, - FlowNodeOutputTypeEnum, - FlowNodeTypeEnum -} from '../../node/constant'; +import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '../../node/constant'; import { FlowNodeTemplateType } from '../../type/index.d'; import { WorkflowIOValueTypeEnum, NodeInputKeyEnum, - FlowNodeTemplateTypeEnum, - NodeOutputKeyEnum + FlowNodeTemplateTypeEnum } from '../../constants'; import { getHandleConfig } from '../utils'; @@ -26,7 +21,7 @@ export const AssignedAnswerModule: FlowNodeTemplateType = { { key: NodeInputKeyEnum.answerText, renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference], - valueType: WorkflowIOValueTypeEnum.string, + valueType: WorkflowIOValueTypeEnum.any, label: 'core.module.input.label.Response content', description: 'core.module.input.description.Response content', placeholder: 'core.module.input.description.Response content' diff --git a/packages/global/core/workflow/template/system/pluginInput.ts b/packages/global/core/workflow/template/system/pluginInput.ts index 177d86ec5..8e0d83f6b 100644 --- a/packages/global/core/workflow/template/system/pluginInput.ts +++ b/packages/global/core/workflow/template/system/pluginInput.ts @@ -12,7 +12,7 @@ export const PluginInputModule: FlowNodeTemplateType = { unique: true, forbidDelete: true, avatar: '/imgs/workflow/input.png', - name: '定义插件输入', + name: '自定义插件输入', intro: '自定义配置外部输入,使用插件时,仅暴露自定义配置的输入', showStatus: false, inputs: [], diff --git a/packages/global/core/workflow/template/system/pluginOutput.ts b/packages/global/core/workflow/template/system/pluginOutput.ts index 9ca82c26e..9b709a3b0 100644 --- a/packages/global/core/workflow/template/system/pluginOutput.ts +++ b/packages/global/core/workflow/template/system/pluginOutput.ts @@ -12,7 +12,7 @@ export const PluginOutputModule: FlowNodeTemplateType = { unique: true, forbidDelete: true, avatar: '/imgs/workflow/output.png', - name: '定义插件输出', + name: '自定义插件输出', intro: '自定义配置外部输出,使用插件时,仅暴露自定义配置的输出', showStatus: false, inputs: [], diff --git a/packages/global/core/workflow/template/system/variableUpdate/index.tsx b/packages/global/core/workflow/template/system/variableUpdate/index.tsx index 24621358e..34ddd2a06 100644 --- a/packages/global/core/workflow/template/system/variableUpdate/index.tsx +++ b/packages/global/core/workflow/template/system/variableUpdate/index.tsx @@ -31,7 +31,8 @@ export const VariableUpdateNode: FlowNodeTemplateType = { value: [ { variable: ['', ''], - value: '', + value: ['', ''], + valueType: WorkflowIOValueTypeEnum.string, renderType: FlowNodeInputTypeEnum.input } ] diff --git a/packages/global/core/workflow/template/system/variableUpdate/type.d.ts b/packages/global/core/workflow/template/system/variableUpdate/type.d.ts index 44e15a1ad..b46d730ee 100644 --- a/packages/global/core/workflow/template/system/variableUpdate/type.d.ts +++ b/packages/global/core/workflow/template/system/variableUpdate/type.d.ts @@ -1,7 +1,10 @@ -import { FlowNodeInputTypeEnum } from 'core/workflow/node/constant'; +import { FlowNodeInputTypeEnum } from '../../../node/constant'; +import { ReferenceValueProps } from '../../..//type/io'; +import { WorkflowIOValueTypeEnum } from '../../../constants'; export type TUpdateListItem = { variable?: ReferenceValueProps; - value?: ReferenceValueProps; - renderType?: FlowNodeInputTypeEnum.input | FlowNodeInputTypeEnum.reference; + value: ReferenceValueProps; + valueType?: WorkflowIOValueTypeEnum; + renderType: FlowNodeInputTypeEnum.input | FlowNodeInputTypeEnum.reference; }; diff --git a/packages/global/core/workflow/type/index.d.ts b/packages/global/core/workflow/type/index.d.ts index 25b9bc876..aca28d433 100644 --- a/packages/global/core/workflow/type/index.d.ts +++ b/packages/global/core/workflow/type/index.d.ts @@ -133,7 +133,7 @@ export type ChatDispatchProps = { responseChatItemId?: string; histories: ChatItemType[]; variables: Record; - inputFiles?: UserChatItemValueItemType['file'][]; + query: UserChatItemValueItemType[]; stream: boolean; detail: boolean; // response detail maxRunTimes: number; diff --git a/packages/global/core/workflow/utils.ts b/packages/global/core/workflow/utils.ts index bd48a7ad9..9a010c823 100644 --- a/packages/global/core/workflow/utils.ts +++ b/packages/global/core/workflow/utils.ts @@ -132,3 +132,7 @@ export const formatEditorVariablePickerIcon = ( icon: item.type ? variableMap[item.type]?.icon : variableMap['input'].icon })); }; + +export const isReferenceValue = (value: any): boolean => { + return Array.isArray(value) && value.length === 2 && typeof value[0] === 'string'; +}; diff --git a/packages/service/core/workflow/dispatch/chat/oneapi.ts b/packages/service/core/workflow/dispatch/chat/oneapi.ts index 67e35df33..10898e40c 100644 --- a/packages/service/core/workflow/dispatch/chat/oneapi.ts +++ b/packages/service/core/workflow/dispatch/chat/oneapi.ts @@ -25,6 +25,7 @@ import { } from '../../../../common/string/tiktoken/index'; import { chats2GPTMessages, + chatValue2RuntimePrompt, getSystemPrompt, GPTMessages2Chats, runtimePrompt2ChatsValue @@ -66,7 +67,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise) => { + const copyVariables = { ...variables }; + delete copyVariables.appId; + delete copyVariables.chatId; + delete copyVariables.responseChatItemId; + delete copyVariables.histories; + delete copyVariables.cTime; + + return copyVariables; +}; + /* Merge consecutive text messages into one */ export const mergeAssistantResponseAnswerText = (response: AIChatItemValueItemType[]) => { const result: AIChatItemValueItemType[] = []; diff --git a/packages/service/core/workflow/dispatch/init/workflowStart.tsx b/packages/service/core/workflow/dispatch/init/workflowStart.tsx index 1960f829b..8b3547b11 100644 --- a/packages/service/core/workflow/dispatch/init/workflowStart.tsx +++ b/packages/service/core/workflow/dispatch/init/workflowStart.tsx @@ -1,15 +1,19 @@ +import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt'; +import { UserChatItemValueItemType } from '@fastgpt/global/core/chat/type'; import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/type/index.d'; export type UserChatInputProps = ModuleDispatchProps<{ [NodeInputKeyEnum.userChatInput]: string; + [NodeInputKeyEnum.inputFiles]: UserChatItemValueItemType['file'][]; }>; export const dispatchWorkflowStart = (props: Record) => { - const { - variables: { userChatInput }, - params: { userChatInput: query } - } = props as UserChatInputProps; + const { query } = props as UserChatInputProps; + + const { text, files } = chatValue2RuntimePrompt(query); + return { - userChatInput: query || userChatInput + [NodeInputKeyEnum.userChatInput]: text, + [NodeInputKeyEnum.inputFiles]: files }; }; diff --git a/packages/service/core/workflow/dispatch/plugin/run.ts b/packages/service/core/workflow/dispatch/plugin/run.ts index 1ef1bcdc1..377e6d210 100644 --- a/packages/service/core/workflow/dispatch/plugin/run.ts +++ b/packages/service/core/workflow/dispatch/plugin/run.ts @@ -1,7 +1,7 @@ import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/type/index.d'; import { dispatchWorkFlow } from '../index'; import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; -import { NodeInputKeyEnum, WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants'; +import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import { getPluginRuntimeById } from '../../../plugin/controller'; import { authPluginCanUse } from '../../../../support/permission/auth/plugin'; diff --git a/packages/service/core/workflow/dispatch/tools/runApp.ts b/packages/service/core/workflow/dispatch/tools/runApp.ts index 747c165a6..df1de2098 100644 --- a/packages/service/core/workflow/dispatch/tools/runApp.ts +++ b/packages/service/core/workflow/dispatch/tools/runApp.ts @@ -35,7 +35,7 @@ export const dispatchAppRequest = async (props: Props): Promise => { stream, detail, histories, - inputFiles, + query, params: { userChatInput, history, app } } = props; let start = Date.now(); @@ -71,7 +71,7 @@ export const dispatchAppRequest = async (props: Props): Promise => { runtimeNodes: storeNodes2RuntimeNodes(appData.modules, getDefaultEntryNodeIds(appData.modules)), runtimeEdges: initWorkflowEdgeStatus(appData.edges), histories: chatHistories, - inputFiles, + query, variables: { ...props.variables, userChatInput @@ -81,10 +81,7 @@ export const dispatchAppRequest = async (props: Props): Promise => { const completeMessages = chatHistories.concat([ { obj: ChatRoleEnum.Human, - value: runtimePrompt2ChatsValue({ - files: inputFiles, - text: userChatInput - }) + value: query }, { obj: ChatRoleEnum.AI, diff --git a/packages/service/core/workflow/dispatch/tools/runUpdateVar.ts b/packages/service/core/workflow/dispatch/tools/runUpdateVar.ts index a8e4f23b1..be337da55 100644 --- a/packages/service/core/workflow/dispatch/tools/runUpdateVar.ts +++ b/packages/service/core/workflow/dispatch/tools/runUpdateVar.ts @@ -4,6 +4,7 @@ import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/ty import { getReferenceVariableValue } from '@fastgpt/global/core/workflow/runtime/utils'; import { TUpdateListItem } from '@fastgpt/global/core/workflow/template/system/variableUpdate/type'; import { ModuleDispatchProps } from '@fastgpt/global/core/workflow/type'; +import { valueTypeFormat } from '../utils'; type Props = ModuleDispatchProps<{ [NodeInputKeyEnum.updateList]: TUpdateListItem[]; @@ -22,26 +23,31 @@ export const dispatchUpdateVariable = async ( if (!varNodeId || !varKey) { return; } - let value = ''; - if (!item.value?.[0]) { - value = item.value?.[1]; - } else { - value = getReferenceVariableValue({ - value: item.value, - variables, - nodes: runtimeNodes - }); - } + + const value = (() => { + if (!item.value?.[0]) { + return valueTypeFormat(item.value?.[1], item.valueType); + } else { + return getReferenceVariableValue({ + value: item.value, + variables, + nodes: runtimeNodes + }); + } + })(); + if (varNodeId === VARIABLE_NODE_ID) { + // update global variable variables[varKey] = value; } else { - const node = runtimeNodes.find((node) => node.nodeId === varNodeId); - if (node) { - const output = node.outputs.find((output) => output.id === varKey); - if (output) { - output.value = value; - } - } + runtimeNodes + .find((node) => node.nodeId === varNodeId) + ?.outputs?.find((output) => { + if (output.id === varKey) { + output.value = value; + return true; + } + }); } }); diff --git a/projects/app/data/pluginTemplates/customFeedback.json b/projects/app/data/pluginTemplates/customFeedback.json index 778211e9d..384bf82c3 100644 --- a/projects/app/data/pluginTemplates/customFeedback.json +++ b/projects/app/data/pluginTemplates/customFeedback.json @@ -10,7 +10,7 @@ "nodes": [ { "nodeId": "lmpb9v2lo2lk", - "name": "定义插件输入", + "name": "自定义插件输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "avatar": "/imgs/workflow/input.png", "flowNodeType": "pluginInput", @@ -76,7 +76,7 @@ }, { "nodeId": "i7uow4wj2wdp", - "name": "定义插件输出", + "name": "自定义插件输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "avatar": "/imgs/workflow/output.png", "flowNodeType": "pluginOutput", diff --git a/projects/app/data/pluginTemplates/getCurrentTime.json b/projects/app/data/pluginTemplates/getCurrentTime.json index 79eaf38a1..9d780f58d 100644 --- a/projects/app/data/pluginTemplates/getCurrentTime.json +++ b/projects/app/data/pluginTemplates/getCurrentTime.json @@ -10,7 +10,7 @@ "nodes": [ { "nodeId": "lmpb9v2lo2lk", - "name": "定义插件输入", + "name": "自定义插件输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "avatar": "/imgs/workflow/input.png", "flowNodeType": "pluginInput", @@ -24,7 +24,7 @@ }, { "nodeId": "i7uow4wj2wdp", - "name": "定义插件输出", + "name": "自定义插件输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "avatar": "/imgs/workflow/output.png", "flowNodeType": "pluginOutput", diff --git a/projects/app/data/pluginTemplates/textEditor.json b/projects/app/data/pluginTemplates/textEditor.json index 0a8caa597..bf37d5733 100644 --- a/projects/app/data/pluginTemplates/textEditor.json +++ b/projects/app/data/pluginTemplates/textEditor.json @@ -10,7 +10,7 @@ "nodes": [ { "nodeId": "lmpb9v2lo2lk", - "name": "定义插件输入", + "name": "自定义插件输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "avatar": "/imgs/workflow/input.png", "flowNodeType": "pluginInput", @@ -77,7 +77,7 @@ }, { "nodeId": "i7uow4wj2wdp", - "name": "定义插件输出", + "name": "自定义插件输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "avatar": "/imgs/workflow/output.png", "flowNodeType": "pluginOutput", diff --git a/projects/app/data/pluginTemplates/v1/customFeedback.json b/projects/app/data/pluginTemplates/v1/customFeedback.json index 9ef9e35f2..cea384399 100644 --- a/projects/app/data/pluginTemplates/v1/customFeedback.json +++ b/projects/app/data/pluginTemplates/v1/customFeedback.json @@ -10,7 +10,7 @@ "modules": [ { "moduleId": "w90mfp", - "name": "定义插件输入", + "name": "自定义插件输入", "flowType": "pluginInput", "showStatus": false, "position": { diff --git a/projects/app/data/pluginTemplates/v1/getCurrentTime.json b/projects/app/data/pluginTemplates/v1/getCurrentTime.json index 235b1f9c6..6d040c788 100644 --- a/projects/app/data/pluginTemplates/v1/getCurrentTime.json +++ b/projects/app/data/pluginTemplates/v1/getCurrentTime.json @@ -10,7 +10,7 @@ "modules": [ { "moduleId": "m8dupj", - "name": "定义插件输入", + "name": "自定义插件输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "avatar": "/imgs/module/input.png", "flowType": "pluginInput", @@ -48,7 +48,7 @@ }, { "moduleId": "bjsa7r", - "name": "定义插件输出", + "name": "自定义插件输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "avatar": "/imgs/module/output.png", "flowType": "pluginOutput", diff --git a/projects/app/data/pluginTemplates/v1/textEditor.json b/projects/app/data/pluginTemplates/v1/textEditor.json index f562f3ec2..444f45a05 100644 --- a/projects/app/data/pluginTemplates/v1/textEditor.json +++ b/projects/app/data/pluginTemplates/v1/textEditor.json @@ -10,7 +10,7 @@ "modules": [ { "moduleId": "w90mfp", - "name": "定义插件输入", + "name": "自定义插件输入", "flowType": "pluginInput", "showStatus": false, "position": { @@ -94,7 +94,7 @@ }, { "moduleId": "tze1ju", - "name": "定义插件输出", + "name": "自定义插件输出", "flowType": "pluginOutput", "showStatus": false, "position": { diff --git a/projects/app/data/pluginTemplates/v1/tfSwitch.json b/projects/app/data/pluginTemplates/v1/tfSwitch.json index fe06dc07f..54cf33bba 100644 --- a/projects/app/data/pluginTemplates/v1/tfSwitch.json +++ b/projects/app/data/pluginTemplates/v1/tfSwitch.json @@ -11,7 +11,7 @@ "modules": [ { "moduleId": "w90mfp", - "name": "定义插件输入", + "name": "自定义插件输入", "flowType": "pluginInput", "showStatus": false, "position": { @@ -78,7 +78,7 @@ }, { "moduleId": "tze1ju", - "name": "定义插件输出", + "name": "自定义插件输出", "flowType": "pluginOutput", "showStatus": false, "position": { diff --git a/projects/app/i18n/en/common.json b/projects/app/i18n/en/common.json index c6ce69d6a..010b9ba03 100644 --- a/projects/app/i18n/en/common.json +++ b/projects/app/i18n/en/common.json @@ -73,6 +73,7 @@ "Confirm Import": "Confirm Import", "Confirm Move": "Move here", "Confirm Update": "Confirm Update", + "Confirm to leave the page": "", "Copy": "Copy", "Copy Successful": "Copied successfully", "Course": "Course", @@ -108,11 +109,15 @@ "Load Failed": "Load Failed", "Loading": "Loading...", "More settings": "More settings", + "MultipleRowSelect": { + "No data": "" + }, "Name": "Name", "Name Can": "Name cannot be empty", "Name is empty": "Name cannot be empty", "New Create": "New Create", "Next Step": "Next", + "No more data": "", "Not open": "Not Open", "Number of words": "{{amount}} words", "OK": "OK", @@ -149,6 +154,7 @@ "Submit failed": "Submit failed", "Submit success": "Submitted successfully", "Sync success": "Sync success", + "System Output": "", "System version": "System Version", "Team": "Team", "Team Tags Set": "Tags", @@ -275,13 +281,24 @@ "Api request desc": "Integrate into existing systems via API, such as WeCom or Feishu", "App intro": "App Introduction", "App params config": "App Configuration", + "Auto Save time": "", + "Change to simple mode": "", "Chat Variable": "Chat Variable", + "Config schedule plan": "", "Config whisper": "Configure Voice Input", "External using": "External Usage", + "Interval timer config": "", + "Interval timer run": "", + "Interval timer tip": "", "Make a brief introduction of your app": "Provide a brief introduction for your AI application", "Max histories": "Max Chat Histories", "Max tokens": "Max Response Tokens", "Name and avatar": "Name & Avatar", + "Onclick to save": "", + "Publish": "", + "Publish Confirm": "", + "Publish Failed": "", + "Publish Success": "", "Question Guide": "Suggested Questions", "Question Guide Tip": "After the conversation ends, 3 guiding questions will be generated.", "Quote prompt": "Quote Template Prompt", @@ -293,6 +310,7 @@ "Select app from template": "Select from Template", "Select quote template": "Select Quote Template", "Set a name for your app": "Set a name for your application", + "Setting ai property": "", "Share link": "Share Link", "Share link desc": "Share link with other users, no login required for direct usage", "Share link desc detail": "You can directly share this model with other users for conversation, without them needing to log in. Note that this feature will consume your account balance, please keep the link secure!", @@ -306,6 +324,7 @@ "Tool call tip": "Automatically select one or more tools to use via the AI model. If this feature is enabled, knowledge base queries will also be considered a tool invocation. Please try to select AI models that support \"function calls\" for better results.", "ToolCall": { "No plugin": "No available plugins", + "Parameter setting": "", "Setting tool": "Configure Tools", "System": "System", "Team": "Team", @@ -358,6 +377,20 @@ "Show History": "Show Chat History", "Web Link": "Web Link" }, + "publish": { + "Fei Shu Bot Desc": "", + "Fei shu bot": "", + "Fei shu bot publish": "" + }, + "schedule": { + "Default prompt": "", + "Default prompt placeholder": "", + "Every day": "", + "Every month": "", + "Every week": "", + "Interval": "", + "Open schedule": "" + }, "setting": "Application Information Settings", "share": { "Amount limit tip": "Maximum 10 groups can be created", @@ -415,6 +448,7 @@ }, "chat": { "Admin Mark Content": "Corrected Response", + "Audio Not Support": "", "Audio Speech Error": "Speech Broadcast Error", "Cancel Speak": "Cancel Voice Input", "Canceled Speak": "Voice input has been canceled", @@ -505,6 +539,7 @@ "module http body": "Request Body", "module http result": "Response Body", "module http url": "Request URL", + "module if else Result": "", "module limit": "Single Search Limit", "module maxToken": "Max Response Tokens", "module model": "Model", @@ -832,6 +867,7 @@ "Input description": "Can accept results from knowledge base search.", "label": "Knowledge Base Quote" }, + "Default Value": "", "Default value": "Default Value", "Default value placeholder": "If left blank, empty string will be returned by default", "Edit intro": "Edit Description", @@ -843,13 +879,22 @@ "Http request settings": "Request Configuration", "Input Type": "Input Type", "Laf sync params": "Sync Parameters", + "Max Length": "", + "Max Length placeholder": "", + "Max Value": "", + "Min Value": "", + "Model List": "", + "No Config Tips": "", + "Output Type": "", "Plugin output must connect": "Custom output must be fully connected", + "Plugin tool Description": "", "QueryExtension": { "placeholder": "For example:\nQuestions about Python introduction and usage.\nThe current conversation is related to the game \"GTA5\".", "tip": "Describe the scope of the current conversation to help AI complete initial or ambiguous questions, enhancing the knowledge base's capability for continuous dialogue. It is recommended to briefly describe the context of the conversation when this feature is enabled, otherwise inaccurate completions may occur." }, "Quote prompt setting": "Quote Prompt Configuration", "Qupte prompt setting": "", + "Select Data List": "", "Select app": "Select Application", "Setting quote prompt": "Configure Quote Prompt", "Unlink tip": "【{{name}}】has unfilled or unconnected parameters", @@ -858,7 +903,8 @@ "Variable import": "External Parameter Input", "edit": { "Field Already Exist": "Duplicate key", - "Field Edit": "Field Edit" + "Field Edit": "Field Edit", + "Field Name Cannot Be Empty": "" }, "extract": { "Add field": "Add Field", @@ -891,8 +937,10 @@ "input": { "Add Input": "Add Input", "Input Number": "Input: {{length}}", + "add": "", "description": { "Background": "You can add introductions to specific content for better identification of user question types. This content is usually used to introduce something the model doesn't know.", + "HTTP Dynamic Input": "", "Http Request Header": "Custom request headers, please fill in strict JSON string.\n1. Ensure the last property has no comma\n2. Ensure keys are wrapped in double quotes\nFor example: {\"Authorization\":\"Bearer xxx\"}", "Http Request Url": "New HTTP request URL. If there are two \"Request URLs\", you can delete the module and add it again to fetch the latest module configuration.", "Quote": "Object array format, structure:\n[{q:'question',a:'answer'}]", @@ -918,6 +966,7 @@ "anyInput": "", "chat history": "Chat History", "switch": "Trigger", + "system params": "", "textEditor textarea": "Text Editor", "user question": "User Question" }, @@ -1014,18 +1063,23 @@ }, "valueType": { "any": "Any", + "arrayBoolean": "", + "arrayNumber": "", + "arrayObject": "", + "arrayString": "", "boolean": "Boolean", "chatHistory": "Chat History", "datasetQuote": "Quote Content", "dynamicTargetInput": "Dynamic Field Input", "number": "Number", + "object": "", "selectApp": "Select Application", "selectDataset": "Select Knowledge Base", "string": "String", "tools": "Tool Invocation" }, "variable": { - "External type": "Externally Passed", + "Custom type": "Custom", "add option": "Add Option", "input type": "Text", "key": "Variable Key", @@ -1076,6 +1130,9 @@ "Stop debug": "Stop", "Success": "Running success", "Value type": "Type", + "Variable": { + "Variable type": "Variable type" + }, "Variable outputs": "Variables", "chat": { "Quote prompt": "Quote prompt" @@ -1707,4 +1764,4 @@ } } } -} \ No newline at end of file +} diff --git a/projects/app/i18n/zh/common.json b/projects/app/i18n/zh/common.json index 258e9137f..ebdafb241 100644 --- a/projects/app/i18n/zh/common.json +++ b/projects/app/i18n/zh/common.json @@ -646,8 +646,7 @@ "success": "开始同步" } }, - "training": { - } + "training": {} }, "data": { "Auxiliary Data": "辅助数据", @@ -975,6 +974,17 @@ "Classify background": "例如: \n1. AIGC(人工智能生成内容)是指使用人工智能技术自动或半自动地生成数字内容,如文本、图像、音乐、视频等。\n2. AIGC技术包括但不限于自然语言处理、计算机视觉、机器学习和深度学习。这些技术可以创建新内容或修改现有内容,以满足特定的创意、教育、娱乐或信息需求。" } }, + "inputType": { + "chat history": "", + "dynamicTargetInput": "", + "input": "", + "selectApp": "", + "selectDataset": "", + "selectLLMModel": "", + "switch": "", + "target": "", + "textarea": "" + }, "laf": { "Select laf function": "选择laf函数" }, @@ -1069,7 +1079,7 @@ "tools": "工具调用" }, "variable": { - "External type": "外部传入", + "Custom type": "自定义变量", "add option": "添加选项", "input type": "文本", "key": "变量 key", @@ -1120,6 +1130,9 @@ "Stop debug": "停止调试", "Success": "运行成功", "Value type": "数据类型", + "Variable": { + "Variable type": "变量类型" + }, "Variable outputs": "全局变量", "chat": { "Quote prompt": "引用提示词" diff --git a/projects/app/src/components/ChatBox/index.tsx b/projects/app/src/components/ChatBox/index.tsx index 0f725e0c2..807e26584 100644 --- a/projects/app/src/components/ChatBox/index.tsx +++ b/projects/app/src/components/ChatBox/index.tsx @@ -160,7 +160,7 @@ const ChatBox = ( /* variable */ const filterVariableModules = useMemo( - () => variableModules.filter((item) => item.type !== VariableInputEnum.external), + () => variableModules.filter((item) => item.type !== VariableInputEnum.custom), [variableModules] ); diff --git a/projects/app/src/components/core/app/VariableEdit.tsx b/projects/app/src/components/core/app/VariableEdit.tsx index aff39f82b..d3eec388c 100644 --- a/projects/app/src/components/core/app/VariableEdit.tsx +++ b/projects/app/src/components/core/app/VariableEdit.tsx @@ -173,7 +173,7 @@ const VariableEdit = ({ maxW={['90vw', '500px']} > - {variableType !== VariableInputEnum.external && ( + {variableType !== VariableInputEnum.custom && ( {t('common.Require Input')} @@ -197,7 +197,7 @@ const VariableEdit = ({ - {t('core.module.Field Type')} + {t('core.workflow.Variable.Variable type')} ) => { const { inputs = [], nodeId } = data; const { t } = useTranslation(); const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode); - const nodes = useContextSelector(WorkflowContext, (v) => v.nodes); const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList); const updateList = useMemo( @@ -65,175 +65,201 @@ const NodeVariableUpdate = ({ data, selected }: NodeProps) => [inputs, nodeId, onChangeNode] ); - const menuList = [ - { - renderType: FlowNodeInputTypeEnum.input, - icon: FlowNodeInputMap[FlowNodeInputTypeEnum.input].icon, - label: t('core.workflow.inputType.Manual input') - }, - { - renderType: FlowNodeInputTypeEnum.reference, - icon: FlowNodeInputMap[FlowNodeInputTypeEnum.reference].icon, - label: t('core.workflow.inputType.Reference') - } - ]; + const Render = useMemo(() => { + const menuList = [ + { + renderType: FlowNodeInputTypeEnum.input, + icon: FlowNodeInputMap[FlowNodeInputTypeEnum.input].icon, + label: t('core.workflow.inputType.Manual input') + }, + { + renderType: FlowNodeInputTypeEnum.reference, + icon: FlowNodeInputMap[FlowNodeInputTypeEnum.reference].icon, + label: t('core.workflow.inputType.Reference') + } + ]; - return ( - - + return ( + <> {updateList.map((updateItem, index) => { - const type = (() => { + const valueType = (() => { const variable = updateItem.variable; const variableNodeId = variable?.[0]; - const variableNode = nodes.find((node) => node.id === variableNodeId); + const variableNode = nodeList.find((node) => node.nodeId === variableNodeId); const systemVariables = getWorkflowGlobalVariables(nodeList, t); + const variableInput = !variableNode ? systemVariables.find((item) => item.key === variable?.[1]) - : variableNode?.data.outputs.find((output) => output.id === variable?.[1]); - if (!variableInput) return 'any'; + : variableNode.outputs.find((output) => output.id === variable?.[1]); + + if (!variableInput) return WorkflowIOValueTypeEnum.any; return variableInput.valueType; })(); const renderTypeData = menuList.find((item) => item.renderType === updateItem.renderType); const handleUpdate = (newValue: ReferenceValueProps | string) => { - if (Array.isArray(newValue)) { + if (isReferenceValue(newValue)) { onUpdateList( updateList.map((update, i) => - i === index ? { ...update, value: newValue } : update + i === index ? { ...update, value: newValue as ReferenceValueProps } : update ) ); } else { onUpdateList( updateList.map((update, i) => - i === index ? { ...update, value: ['', newValue] } : update + i === index ? { ...update, value: ['', newValue as string] } : update ) ); } }; + return ( - - - - {t('core.workflow.variable')} - { - onUpdateList( - updateList.map((update, i) => { - if (i === index) { - return { - ...update, - variable: value - }; - } - return update; - }) - ); + + + {t('core.workflow.variable')} + { + onUpdateList( + updateList.map((update, i) => { + if (i === index) { + return { + ...update, + value: ['', ''], + valueType, + variable: value + }; + } + return update; + }) + ); + }} + /> + + {updateList.length > 1 && ( + { + onUpdateList(updateList.filter((_, i) => i !== index)); }} /> - - {updateList.length > 1 && ( - + + + {t('core.workflow.value')} + item.renderType === updateItem.renderType)?.label + } + > + - - - {updateItem.renderType === FlowNodeInputTypeEnum.reference ? ( - - ) : ( - <> - {type === 'string' && ( -