From e05ae8a3ec5d68efd896e64312c9380edf7cdc0f Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Tue, 24 Mar 2026 09:59:30 +0800 Subject: [PATCH] fix: child workflow variable default value not init (#6620) --- .../docs/self-host/upgrading/4-14/41410.mdx | 15 ++++ .../docs/self-host/upgrading/4-14/meta.json | 15 +++- document/content/docs/toc.mdx | 1 + document/data/doc-last-modified.json | 2 +- .../core/workflow/dispatch/child/runApp.ts | 22 +++-- .../service/core/workflow/dispatch/index.ts | 85 ++++--------------- .../service/core/workflow/dispatch/utils.ts | 70 +++++++++++++++ 7 files changed, 134 insertions(+), 76 deletions(-) create mode 100644 document/content/docs/self-host/upgrading/4-14/41410.mdx diff --git a/document/content/docs/self-host/upgrading/4-14/41410.mdx b/document/content/docs/self-host/upgrading/4-14/41410.mdx new file mode 100644 index 0000000000..25479ab1f0 --- /dev/null +++ b/document/content/docs/self-host/upgrading/4-14/41410.mdx @@ -0,0 +1,15 @@ +--- +title: 'V4.14.10(进行中)' +description: 'FastGPT V4.14.10 更新说明' +--- + + +## 🚀 新增内容 + + +## ⚙️ 优化 + + +## 🐛 修复 + +1. 子工作流的全局变量默认值未生效。 \ No newline at end of file diff --git a/document/content/docs/self-host/upgrading/4-14/meta.json b/document/content/docs/self-host/upgrading/4-14/meta.json index 8156ffb8e7..4cfe6c55eb 100644 --- a/document/content/docs/self-host/upgrading/4-14/meta.json +++ b/document/content/docs/self-host/upgrading/4-14/meta.json @@ -1,5 +1,18 @@ { "title": "4.14.x", "description": "", - "pages": ["4149", "4148", "4147", "4146", "41451", "4145", "4144", "4143", "4142", "4141", "4140"] + "pages": [ + "41410", + "4149", + "4148", + "4147", + "4146", + "41451", + "4145", + "4144", + "4143", + "4142", + "4141", + "4140" + ] } diff --git a/document/content/docs/toc.mdx b/document/content/docs/toc.mdx index e77ce6c342..9ba7b62969 100644 --- a/document/content/docs/toc.mdx +++ b/document/content/docs/toc.mdx @@ -112,6 +112,7 @@ description: FastGPT 文档目录 - [/docs/self-host/upgrading/4-13/4132](/docs/self-host/upgrading/4-13/4132) - [/docs/self-host/upgrading/4-14/4140](/docs/self-host/upgrading/4-14/4140) - [/docs/self-host/upgrading/4-14/4141](/docs/self-host/upgrading/4-14/4141) +- [/docs/self-host/upgrading/4-14/41410](/docs/self-host/upgrading/4-14/41410) - [/docs/self-host/upgrading/4-14/4142](/docs/self-host/upgrading/4-14/4142) - [/docs/self-host/upgrading/4-14/4143](/docs/self-host/upgrading/4-14/4143) - [/docs/self-host/upgrading/4-14/4144](/docs/self-host/upgrading/4-14/4144) diff --git a/document/data/doc-last-modified.json b/document/data/doc-last-modified.json index 4562876fe1..1465c56230 100644 --- a/document/data/doc-last-modified.json +++ b/document/data/doc-last-modified.json @@ -239,7 +239,7 @@ "document/content/docs/self-host/upgrading/4-14/41481.en.mdx": "2026-03-09T12:02:02+08:00", "document/content/docs/self-host/upgrading/4-14/41481.mdx": "2026-03-09T17:39:53+08:00", "document/content/docs/self-host/upgrading/4-14/4149.en.mdx": "2026-03-23T12:17:04+08:00", - "document/content/docs/self-host/upgrading/4-14/4149.mdx": "2026-03-23T23:36:16+08:00", + "document/content/docs/self-host/upgrading/4-14/4149.mdx": "2026-03-23T23:36:27+08:00", "document/content/docs/self-host/upgrading/outdated/40.en.mdx": "2026-03-03T17:39:47+08:00", "document/content/docs/self-host/upgrading/outdated/40.mdx": "2026-03-03T17:39:47+08:00", "document/content/docs/self-host/upgrading/outdated/41.en.mdx": "2026-03-03T17:39:47+08:00", diff --git a/packages/service/core/workflow/dispatch/child/runApp.ts b/packages/service/core/workflow/dispatch/child/runApp.ts index d12bb514ba..56468edd0a 100644 --- a/packages/service/core/workflow/dispatch/child/runApp.ts +++ b/packages/service/core/workflow/dispatch/child/runApp.ts @@ -13,7 +13,7 @@ import { import type { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants'; -import { filterSystemVariables, getNodeErrResponse, getHistories } from '../utils'; +import { getSystemVariables, getNodeErrResponse, getHistories } from '../utils'; import { chatValue2RuntimePrompt, runtimePrompt2ChatsValue } from '@fastgpt/global/core/chat/adapt'; import { type DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type'; import { authAppByTmbId } from '../../../../support/permission/app/auth'; @@ -100,13 +100,23 @@ export const dispatchRunAppNode = async (props: Props): Promise => { const chatHistories = getHistories(history, histories); // Rewrite children app variables - const systemVariables = filterSystemVariables(variables); const { externalProvider } = await getUserChatInfo(appData.tmbId); const childrenRunVariables = { - ...systemVariables, - ...childrenAppVariables, - histories: chatHistories, - appId: String(appData._id), + ...(await getSystemVariables({ + timezone: props.timezone, + runningAppInfo: { + id: String(appData._id), + teamId: appData.teamId, + tmbId: appData.tmbId, + name: appData.name + }, + chatId: props.chatId, + responseChatItemId: props.responseChatItemId, + histories: chatHistories, + uid: props.uid, + chatConfig, + variables: childrenAppVariables + })), ...(externalProvider ? externalProvider.externalWorkflowVariables : {}) }; diff --git a/packages/service/core/workflow/dispatch/index.ts b/packages/service/core/workflow/dispatch/index.ts index 529b093bb3..d86b7de94a 100644 --- a/packages/service/core/workflow/dispatch/index.ts +++ b/packages/service/core/workflow/dispatch/index.ts @@ -1,5 +1,4 @@ import { getNanoid } from '@fastgpt/global/common/string/tools'; -import { getSystemTime } from '@fastgpt/global/common/time/timezone'; import { SpanStatusCode } from '@opentelemetry/api'; import type { AIChatItemValueItemType, @@ -12,7 +11,7 @@ import type { NodeOutputItemType } from '@fastgpt/global/core/workflow/runtime/type'; import type { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; -import { NodeInputKeyEnum, VariableInputEnum } from '@fastgpt/global/core/workflow/constants'; +import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { FlowNodeInputTypeEnum, FlowNodeTypeEnum @@ -24,8 +23,7 @@ import { import type { ChatDispatchProps, DispatchNodeResultType, - ModuleDispatchProps, - SystemVariablesType + ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type'; import type { RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type'; import { getErrText, UserError } from '@fastgpt/global/common/error/utils'; @@ -46,17 +44,21 @@ import type { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type import { getLogger, LogCategories } from '../../../common/logger'; import { surrenderProcess } from '../../../common/system/tools'; import type { DispatchFlowResponse, WorkflowDebugResponse } from './type'; -import { rewriteRuntimeWorkFlow, runtimeSystemVar2StoreType, filterOrphanEdges } from './utils'; +import { + rewriteRuntimeWorkFlow, + runtimeSystemVar2StoreType, + filterOrphanEdges, + getSystemVariables +} from './utils'; import { getHandleId } from '@fastgpt/global/core/workflow/utils'; import { callbackMap } from './constants'; -import { anyValueDecrypt } from '../../../common/secret/utils'; import { getUserChatInfo } from '../../../support/user/team/utils'; import { checkTeamAIPoints } from '../../../support/permission/teamLimit'; import type { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants'; import { createChatUsageRecord, pushChatItemUsage } from '../../../support/wallet/usage/controller'; import type { RequireOnlyOne } from '@fastgpt/global/common/type/utils'; import { getS3ChatSource } from '../../../common/s3/sources/chat'; -import { addPreviewUrlToChatItems, presignVariablesFileUrls } from '../../chat/utils'; +import { addPreviewUrlToChatItems } from '../../chat/utils'; import { TeamErrEnum } from '@fastgpt/global/common/error/code/team'; import { i18nT } from '../../../../web/i18n/utils'; import { validateFileUrlDomain } from '../../../common/security/fileUrlValidator'; @@ -192,10 +194,14 @@ export async function dispatchWorkFlow({ const defaultVariables = { ...externalProvider.externalWorkflowVariables, ...(await getSystemVariables({ - ...data, - query, - histories, - timezone + runningAppInfo: runningAppInfo, + chatId: chatId, + responseChatItemId: data.responseChatItemId, + histories: histories, + uid: data.uid, + chatConfig: data.chatConfig, + variables: data.variables, + timezone: timezone })) }; @@ -1538,63 +1544,6 @@ export const runWorkflow = async (data: RunWorkflowProps): Promise => { - // Get global variables(Label -> key; Key -> key) - const variablesConfig = chatConfig?.variables || []; - - const variablesMap: Record = {}; - for await (const item of variablesConfig) { - // For internal variables, ignore external input and use default value - if (item.type === VariableInputEnum.password) { - const val = variables[item.label] || variables[item.key] || item.defaultValue; - const actualValue = anyValueDecrypt(val); - variablesMap[item.key] = valueTypeFormat(actualValue, item.valueType); - } - // 文件类型全局变量,签发成 string[] 格式 - else if (item.type === VariableInputEnum.file) { - const vars = await presignVariablesFileUrls({ - variables, - variableConfig: [item] - }); - - variablesMap[item.key] = vars?.[item.key]?.map((item: any) => item.url); - } - // API - else if (variables[item.label] !== undefined) { - variablesMap[item.key] = valueTypeFormat(variables[item.label], item.valueType); - } - // Web - else if (variables[item.key] !== undefined) { - variablesMap[item.key] = valueTypeFormat(variables[item.key], item.valueType); - } else { - variablesMap[item.key] = valueTypeFormat(item.defaultValue, item.valueType); - } - } - - return { - ...variablesMap, - // System var: - userId: uid, - appId: String(runningAppInfo.id), - chatId, - responseChatItemId, - histories, - cTime: getSystemTime(timezone) - }; -}; - /* Merge consecutive text messages into one */ const mergeAssistantResponseAnswerText = (response: AIChatItemValueItemType[]) => { const result: AIChatItemValueItemType[] = []; diff --git a/packages/service/core/workflow/dispatch/utils.ts b/packages/service/core/workflow/dispatch/utils.ts index 7891991516..02ad3363f6 100644 --- a/packages/service/core/workflow/dispatch/utils.ts +++ b/packages/service/core/workflow/dispatch/utils.ts @@ -6,6 +6,8 @@ import { NodeOutputKeyEnum, VariableInputEnum } from '@fastgpt/global/core/workf import type { VariableItemType } from '@fastgpt/global/core/app/type'; import { encryptSecret } from '../../../common/secret/aes256gcm'; import { imageFileType } from '@fastgpt/global/common/file/constants'; +import type { + ChatDispatchProps} from '@fastgpt/global/core/workflow/runtime/type'; import { type RuntimeNodeItemType, type SystemVariablesType @@ -30,6 +32,74 @@ import type { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type import type { HttpToolConfigType } from '@fastgpt/global/core/app/tool/httpTool/type'; import type { WorkflowResponseType } from './type'; import { getLogger, LogCategories } from '../../../common/logger'; +import { anyValueDecrypt } from '../../../common/secret/utils'; +import { valueTypeFormat } from '@fastgpt/global/core/workflow/runtime/utils'; +import { presignVariablesFileUrls } from '../../chat/utils'; +import { getSystemTime } from '@fastgpt/global/common/time/timezone'; + +/* get system variable */ +export const getSystemVariables = async ({ + timezone, + runningAppInfo, + chatId, + responseChatItemId, + histories = [], + uid, + chatConfig, + variables +}: { + runningAppInfo: ChatDispatchProps['runningAppInfo']; + chatId: ChatDispatchProps['chatId']; + responseChatItemId: ChatDispatchProps['responseChatItemId']; + histories: ChatDispatchProps['histories']; + uid: ChatDispatchProps['uid']; + chatConfig: ChatDispatchProps['chatConfig']; + variables: ChatDispatchProps['variables']; + timezone: string; +}): Promise => { + // Get global variables(Label -> key; Key -> key) + const variablesConfig = chatConfig?.variables || []; + + const variablesMap: Record = {}; + for await (const item of variablesConfig) { + // For internal variables, ignore external input and use default value + if (item.type === VariableInputEnum.password) { + const val = variables[item.label] || variables[item.key] || item.defaultValue; + const actualValue = anyValueDecrypt(val); + variablesMap[item.key] = valueTypeFormat(actualValue, item.valueType); + } + // 文件类型全局变量,签发成 string[] 格式 + else if (item.type === VariableInputEnum.file) { + const vars = await presignVariablesFileUrls({ + variables, + variableConfig: [item] + }); + + variablesMap[item.key] = vars?.[item.key]?.map((item: any) => item.url); + } + // API + else if (variables[item.label] !== undefined) { + variablesMap[item.key] = valueTypeFormat(variables[item.label], item.valueType); + } + // Web + else if (variables[item.key] !== undefined) { + variablesMap[item.key] = valueTypeFormat(variables[item.key], item.valueType); + } else { + variablesMap[item.key] = valueTypeFormat(item.defaultValue, item.valueType); + } + } + + return { + ...variablesMap, + // System var: + userId: uid, + appId: String(runningAppInfo.id), + chatId, + responseChatItemId, + histories, + cTime: getSystemTime(timezone) + }; +}; export const getWorkflowResponseWrite = ({ res,