fix: child workflow variable default value not init (#6620)

This commit is contained in:
Archer
2026-03-24 09:59:30 +08:00
committed by GitHub
parent 37bbccdc1f
commit e05ae8a3ec
7 changed files with 134 additions and 76 deletions
@@ -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<Response> => {
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 : {})
};
@@ -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<DispatchFlowR
);
};
/* get system variable */
const getSystemVariables = async ({
timezone,
runningAppInfo,
chatId,
responseChatItemId,
histories = [],
uid,
chatConfig,
variables
}: Props & {
timezone: string;
}): Promise<SystemVariablesType> => {
// Get global variables(Label -> key; Key -> key)
const variablesConfig = chatConfig?.variables || [];
const variablesMap: Record<string, any> = {};
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[] = [];
@@ -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<SystemVariablesType> => {
// Get global variables(Label -> key; Key -> key)
const variablesConfig = chatConfig?.variables || [];
const variablesMap: Record<string, any> = {};
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,