feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-magic-numbers */
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
/**
|
||||
* 使用 V2 版本异常设置的节点
|
||||
*/
|
||||
export const SETTING_ON_ERROR_V2_NODES = [
|
||||
StandardNodeType.Code,
|
||||
StandardNodeType.LLM,
|
||||
StandardNodeType.Api,
|
||||
StandardNodeType.Database,
|
||||
StandardNodeType.ImageGenerate,
|
||||
StandardNodeType.DatabaseCreate,
|
||||
StandardNodeType.DatabaseUpdate,
|
||||
StandardNodeType.DatabaseQuery,
|
||||
StandardNodeType.DatabaseDelete,
|
||||
StandardNodeType.ImageCanvas,
|
||||
StandardNodeType.Intent,
|
||||
];
|
||||
|
||||
/**
|
||||
* 使用V1的版本异常设置
|
||||
*/
|
||||
export const SETTING_ON_ERROR_V1_NODES = [StandardNodeType.Http];
|
||||
|
||||
/**
|
||||
* 有动态port的节点
|
||||
*/
|
||||
export const SETTING_ON_ERROR_DYNAMIC_PORT_NODES = [StandardNodeType.Intent];
|
||||
|
||||
/**
|
||||
* 开启异常的节点
|
||||
*/
|
||||
export const SETTING_ON_ERROR_NODES = [
|
||||
...SETTING_ON_ERROR_V1_NODES,
|
||||
...SETTING_ON_ERROR_V2_NODES,
|
||||
];
|
||||
|
||||
/**
|
||||
* 异常端口
|
||||
*/
|
||||
export const SETTING_ON_ERROR_PORT = 'branch_error';
|
||||
|
||||
/**
|
||||
* 超时最小100ms;
|
||||
*/
|
||||
export const SETTING_ON_ERROR_MIN_TIMEOUT = 100;
|
||||
|
||||
/**
|
||||
* 其他节点:默认1分钟,最大1分钟;
|
||||
*/
|
||||
export const SETTING_ON_ERROR_DEFAULT_TIMEOUT = {
|
||||
default: 60 * 1000,
|
||||
max: 60 * 1000,
|
||||
};
|
||||
|
||||
/**
|
||||
* 节点配置
|
||||
* LLM:默认3分钟,最大10分钟;
|
||||
* 插件:默认3分钟,最大3分钟;
|
||||
*/
|
||||
export const SETTING_ON_ERROR_NODES_CONFIG = {
|
||||
[StandardNodeType.LLM]: {
|
||||
timeout: {
|
||||
default: 3 * 60 * 1000,
|
||||
max: 10 * 60 * 1000,
|
||||
init: 10 * 60 * 1000,
|
||||
},
|
||||
enableBackupModel: true,
|
||||
},
|
||||
[StandardNodeType.Api]: {
|
||||
timeout: {
|
||||
default: 3 * 60 * 1000,
|
||||
max: 3 * 60 * 1000,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const ERROR_BODY_NAME = 'errorBody';
|
||||
export const IS_SUCCESS_NAME = 'isSuccess';
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type ViewVariableTreeNode,
|
||||
type StandardNodeType,
|
||||
} from '@coze-workflow/base';
|
||||
import { type NodeContext } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { formatModelData } from '../utils';
|
||||
import { getOutputsWithErrorBody } from './utils/outputs';
|
||||
import { getTimeoutConfig } from './utils/get-timeout-config';
|
||||
import { isSettingOnErrorV2 } from './utils';
|
||||
import {
|
||||
type SettingOnErrorDTO,
|
||||
SettingOnErrorProcessType,
|
||||
type SettingOnErrorExt,
|
||||
type NodeValueWithSettingOnErrorDTO,
|
||||
type NodeValueWithSettingOnErrorVO,
|
||||
type SettingOnErrorVO,
|
||||
} from './types';
|
||||
|
||||
const formatExtOnInit = (ext: SettingOnErrorDTO['ext']) => {
|
||||
if (!ext) {
|
||||
return ext;
|
||||
}
|
||||
const llmParam = ext?.backupLLmParam;
|
||||
|
||||
return {
|
||||
backupLLmParam: llmParam ? JSON.parse(llmParam) : undefined,
|
||||
};
|
||||
};
|
||||
|
||||
const getDTOProcessType = (settingOnError?: SettingOnErrorDTO) =>
|
||||
settingOnError?.processType ||
|
||||
(settingOnError?.switch
|
||||
? SettingOnErrorProcessType.RETURN
|
||||
: SettingOnErrorProcessType.BREAK);
|
||||
|
||||
const settingOnErrorInitV2 = (
|
||||
settingOnError?: SettingOnErrorDTO,
|
||||
context?: NodeContext,
|
||||
value?: NodeValueWithSettingOnErrorDTO,
|
||||
) => {
|
||||
if (!isNodeContextV2(context)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
let timeoutMs = settingOnError?.timeoutMs;
|
||||
const timeoutConfig = getTimeoutConfig(context?.node);
|
||||
|
||||
if (!timeoutMs) {
|
||||
// 如果没有设置超时时间,且有初始值配置,则设置初始值
|
||||
// 如LLM后端默认是10min,历史数据需要设置为init的10min,新加的节点显示默认的default的3min
|
||||
if (value && timeoutConfig?.init) {
|
||||
timeoutMs = timeoutConfig.init;
|
||||
} else {
|
||||
timeoutMs = timeoutConfig?.default;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
processType: getDTOProcessType(settingOnError),
|
||||
timeoutMs,
|
||||
retryTimes: settingOnError?.retryTimes ?? 0,
|
||||
ext: formatExtOnInit(settingOnError?.ext),
|
||||
};
|
||||
};
|
||||
|
||||
const formatExtOnSave = (
|
||||
ext: SettingOnErrorExt | undefined,
|
||||
playgroundContext,
|
||||
) => {
|
||||
if (!ext) {
|
||||
return ext;
|
||||
}
|
||||
const models = playgroundContext?.models || [];
|
||||
const llmParam = ext.backupLLmParam;
|
||||
const modelMeta = models.find(m => m.model_type === llmParam?.modelType);
|
||||
|
||||
return {
|
||||
backupLLmParam: llmParam
|
||||
? JSON.stringify(formatModelData(llmParam, modelMeta))
|
||||
: undefined,
|
||||
};
|
||||
};
|
||||
|
||||
const settingOnErrorSaveV2 = (
|
||||
settingOnError: SettingOnErrorVO,
|
||||
context?: NodeContext,
|
||||
) => {
|
||||
const playgroundContext = context?.playgroundContext;
|
||||
const res: Partial<SettingOnErrorDTO> = {
|
||||
processType:
|
||||
settingOnError?.processType ||
|
||||
(settingOnError?.settingOnErrorIsOpen
|
||||
? SettingOnErrorProcessType.RETURN
|
||||
: undefined),
|
||||
timeoutMs: settingOnError?.timeoutMs,
|
||||
retryTimes: settingOnError?.retryTimes,
|
||||
};
|
||||
|
||||
if (settingOnError?.retryTimes) {
|
||||
res.ext = formatExtOnSave(settingOnError?.ext, playgroundContext);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
const isNodeContextV2 = (context?: NodeContext) =>
|
||||
isSettingOnErrorV2(context?.node?.flowNodeType as StandardNodeType);
|
||||
|
||||
export const settingOnErrorToVO = (
|
||||
settingOnError?: SettingOnErrorDTO,
|
||||
context?: NodeContext,
|
||||
value?: NodeValueWithSettingOnErrorDTO,
|
||||
): SettingOnErrorVO => ({
|
||||
settingOnErrorIsOpen: settingOnError?.switch,
|
||||
settingOnErrorJSON: settingOnError?.dataOnErr,
|
||||
...settingOnErrorInitV2(settingOnError, context, value),
|
||||
});
|
||||
|
||||
export const settingOnErrorToDTO = (
|
||||
settingOnError?: SettingOnErrorVO,
|
||||
context?: NodeContext,
|
||||
) => {
|
||||
if (!settingOnError) {
|
||||
return settingOnError;
|
||||
}
|
||||
|
||||
return {
|
||||
switch: settingOnError?.settingOnErrorIsOpen,
|
||||
dataOnErr: settingOnError?.settingOnErrorJSON,
|
||||
...(isNodeContextV2(context)
|
||||
? settingOnErrorSaveV2(settingOnError, context)
|
||||
: {}),
|
||||
};
|
||||
};
|
||||
|
||||
export const formatOutputsOnInit = (
|
||||
value?: NodeValueWithSettingOnErrorDTO,
|
||||
context?: NodeContext,
|
||||
) => {
|
||||
const outputs = value?.outputs;
|
||||
const isV2 = isNodeContextV2(context);
|
||||
const isOpen = !!value?.inputs?.settingOnError?.switch;
|
||||
|
||||
if (!outputs || !isSettingOnErrorV2 || !isOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isBatch = !!value?.inputs?.batch?.batchEnable;
|
||||
return getOutputsWithErrorBody({
|
||||
value: outputs,
|
||||
isBatch,
|
||||
isOpen,
|
||||
isSettingOnErrorV2: isV2,
|
||||
});
|
||||
};
|
||||
|
||||
export const settingOnErrorInit = (
|
||||
value?: NodeValueWithSettingOnErrorDTO,
|
||||
context?: NodeContext,
|
||||
): {
|
||||
settingOnError?: SettingOnErrorVO;
|
||||
outputs?: ViewVariableTreeNode[];
|
||||
} => {
|
||||
const outputs = formatOutputsOnInit(value, context);
|
||||
|
||||
return {
|
||||
settingOnError: settingOnErrorToVO(
|
||||
value?.inputs?.settingOnError,
|
||||
context,
|
||||
value,
|
||||
),
|
||||
...(outputs ? { outputs } : {}),
|
||||
};
|
||||
};
|
||||
|
||||
export const settingOnErrorSave = (
|
||||
value: NodeValueWithSettingOnErrorVO,
|
||||
context: NodeContext | undefined = undefined,
|
||||
) => {
|
||||
const settingOnError = value?.settingOnError;
|
||||
if (value?.settingOnError) {
|
||||
delete value.settingOnError;
|
||||
}
|
||||
|
||||
return {
|
||||
settingOnError: settingOnErrorToDTO(settingOnError, context),
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type StandardNodeType } from '@coze-workflow/base/types';
|
||||
import { useCurrentEntity } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { isSettingOnErrorV2, isSettingOnError } from '../utils';
|
||||
|
||||
export const useIsSettingOnErrorV2 = () => {
|
||||
const node = useCurrentEntity();
|
||||
|
||||
return isSettingOnErrorV2(node.flowNodeType as StandardNodeType);
|
||||
};
|
||||
|
||||
export const useIsSettingOnError = () => {
|
||||
const node = useCurrentEntity();
|
||||
|
||||
return isSettingOnError(node.flowNodeType as StandardNodeType);
|
||||
};
|
||||
|
||||
export { useTimeoutConfig } from './use-timeout-config';
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useCurrentEntity } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { getTimeoutConfig } from '../utils/get-timeout-config';
|
||||
|
||||
/**
|
||||
* 获取超时配置
|
||||
* @returns
|
||||
*/
|
||||
export const useTimeoutConfig = (): {
|
||||
default: number;
|
||||
max: number;
|
||||
min: number;
|
||||
disabled: boolean;
|
||||
} => {
|
||||
const node = useCurrentEntity();
|
||||
return getTimeoutConfig(node);
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export {
|
||||
SettingOnErrorProcessType,
|
||||
type SettingOnErrorExt,
|
||||
type SettingOnErrorVO,
|
||||
type SettingOnErrorValue,
|
||||
} from './types';
|
||||
|
||||
export {
|
||||
settingOnErrorInit,
|
||||
settingOnErrorSave,
|
||||
settingOnErrorToDTO,
|
||||
settingOnErrorToVO,
|
||||
} from './data-transformer';
|
||||
export {
|
||||
isSettingOnError,
|
||||
isSettingOnErrorV2,
|
||||
isSettingOnErrorDynamicPort,
|
||||
} from './utils';
|
||||
export {
|
||||
generateErrorBodyMeta,
|
||||
generateIsSuccessMeta,
|
||||
} from './utils/generate-meta';
|
||||
export {
|
||||
useIsSettingOnError,
|
||||
useIsSettingOnErrorV2,
|
||||
useTimeoutConfig,
|
||||
} from './hooks';
|
||||
export {
|
||||
SETTING_ON_ERROR_PORT,
|
||||
SETTING_ON_ERROR_NODES_CONFIG,
|
||||
ERROR_BODY_NAME,
|
||||
IS_SUCCESS_NAME,
|
||||
} from './constants';
|
||||
export {
|
||||
getOutputsWithErrorBody,
|
||||
sortErrorBody,
|
||||
getExcludeErrorBody,
|
||||
} from './utils/outputs';
|
||||
124
frontend/packages/workflow/nodes/src/setting-on-error/types.ts
Normal file
124
frontend/packages/workflow/nodes/src/setting-on-error/types.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type ViewVariableTreeNode } from '@coze-workflow/base';
|
||||
|
||||
/**
|
||||
* 异常处理类型
|
||||
* 1 直接中断
|
||||
* 2 返回设定内容,
|
||||
* 3 执行异常流程
|
||||
*/
|
||||
export enum SettingOnErrorProcessType {
|
||||
BREAK = 1,
|
||||
RETURN = 2,
|
||||
EXCEPTION = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常处理额外数据
|
||||
*/
|
||||
export interface SettingOnErrorExt {
|
||||
/**
|
||||
* LLM节点重试的备选模型
|
||||
*/
|
||||
backupLLmParam?: {
|
||||
modelName?: string;
|
||||
modelType?: number;
|
||||
temperature?: number;
|
||||
frequencyPenalty?: number;
|
||||
presencePenalty?: number;
|
||||
topP?: number;
|
||||
topK?: number;
|
||||
maxTokens?: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface SettingOnErrorBase {
|
||||
/**
|
||||
* 处理类型
|
||||
*/
|
||||
processType?: SettingOnErrorProcessType;
|
||||
/**
|
||||
* 超时时间 毫秒
|
||||
*/
|
||||
timeoutMs?: number;
|
||||
/**
|
||||
* 重试次数 0 表示不重试
|
||||
*/
|
||||
retryTimes?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常处理前端结构
|
||||
*/
|
||||
export interface SettingOnErrorVO extends SettingOnErrorBase {
|
||||
/**
|
||||
* 是否开启异常处理
|
||||
*/
|
||||
settingOnErrorIsOpen?: boolean;
|
||||
/**
|
||||
* 发生异常处理的默认值
|
||||
*/
|
||||
settingOnErrorJSON?: string;
|
||||
|
||||
/**
|
||||
* 其他设置
|
||||
*/
|
||||
ext?: SettingOnErrorExt;
|
||||
}
|
||||
|
||||
export type SettingOnErrorValue = SettingOnErrorVO;
|
||||
|
||||
/**
|
||||
* 异常处理后端结构
|
||||
*/
|
||||
export interface SettingOnErrorDTO extends SettingOnErrorBase {
|
||||
/**
|
||||
* 是否开启异常处理
|
||||
*/
|
||||
switch: boolean;
|
||||
/**
|
||||
* 发生异常处理的默认值
|
||||
*/
|
||||
dataOnErr: string;
|
||||
/**
|
||||
* 其他设置
|
||||
*/
|
||||
ext?: {
|
||||
backupLLmParam?: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 有异常设置的后端节点数据
|
||||
*/
|
||||
export interface NodeValueWithSettingOnErrorDTO {
|
||||
inputs?: {
|
||||
settingOnError?: SettingOnErrorDTO;
|
||||
batch?: {
|
||||
batchEnable?: boolean;
|
||||
};
|
||||
};
|
||||
outputs?: ViewVariableTreeNode[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 有异常设置的前端节点数据
|
||||
*/
|
||||
export interface NodeValueWithSettingOnErrorVO {
|
||||
settingOnError?: SettingOnErrorVO;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import {
|
||||
SETTING_ON_ERROR_DYNAMIC_PORT_NODES,
|
||||
SETTING_ON_ERROR_NODES,
|
||||
SETTING_ON_ERROR_V2_NODES,
|
||||
} from './constants';
|
||||
|
||||
/**
|
||||
* 是不是v2版本的节点
|
||||
* @param type
|
||||
* @returns
|
||||
*/
|
||||
export const isSettingOnErrorV2 = (type?: StandardNodeType) =>
|
||||
type && SETTING_ON_ERROR_V2_NODES.includes(type);
|
||||
|
||||
/**
|
||||
* 是不是开启异常设置的节点
|
||||
* @param type
|
||||
* @returns
|
||||
*/
|
||||
export const isSettingOnError = (type?: StandardNodeType) =>
|
||||
type && SETTING_ON_ERROR_NODES.includes(type);
|
||||
|
||||
/**
|
||||
* 是不是动态通道的节点
|
||||
* @param type
|
||||
* @returns
|
||||
*/
|
||||
export const isSettingOnErrorDynamicPort = (type?: StandardNodeType) =>
|
||||
type && SETTING_ON_ERROR_DYNAMIC_PORT_NODES.includes(type);
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ViewVariableType } from '@coze-workflow/base';
|
||||
|
||||
import { ERROR_BODY_NAME, IS_SUCCESS_NAME } from '../constants';
|
||||
|
||||
export const generateErrorBodyMeta = () => ({
|
||||
key: nanoid(),
|
||||
name: ERROR_BODY_NAME,
|
||||
type: ViewVariableType.Object,
|
||||
readonly: true,
|
||||
children: [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'errorMessage',
|
||||
type: ViewVariableType.String,
|
||||
readonly: true,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'errorCode',
|
||||
type: ViewVariableType.String,
|
||||
readonly: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const generateIsSuccessMeta = () => ({
|
||||
key: nanoid(),
|
||||
name: IS_SUCCESS_NAME,
|
||||
type: ViewVariableType.Boolean,
|
||||
readonly: true,
|
||||
});
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { get } from 'lodash-es';
|
||||
import { PluginType, StandardNodeType } from '@coze-workflow/base';
|
||||
import { type WorkflowNodeEntity } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
SETTING_ON_ERROR_DEFAULT_TIMEOUT,
|
||||
SETTING_ON_ERROR_MIN_TIMEOUT,
|
||||
SETTING_ON_ERROR_NODES_CONFIG,
|
||||
} from '../constants';
|
||||
import { WorkflowNodeData } from '../../entity-datas';
|
||||
|
||||
/**
|
||||
* 是不是端插件
|
||||
* @param node
|
||||
* @returns
|
||||
*/
|
||||
const isLocalPlugin = (node?: WorkflowNodeEntity) => {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const nodeDataEntity = node.getData<WorkflowNodeData>(WorkflowNodeData);
|
||||
const nodeData = nodeDataEntity?.getNodeData();
|
||||
|
||||
return !!(
|
||||
node?.flowNodeType === StandardNodeType.Api &&
|
||||
get(nodeData, 'pluginType') === PluginType.LOCAL
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取节点超时配置
|
||||
*/
|
||||
export const getTimeoutConfig = (
|
||||
node?: WorkflowNodeEntity,
|
||||
): {
|
||||
max: number;
|
||||
default: number;
|
||||
min: number;
|
||||
init?: number;
|
||||
disabled: boolean;
|
||||
} => {
|
||||
let timeoutConfig = SETTING_ON_ERROR_DEFAULT_TIMEOUT;
|
||||
|
||||
if (
|
||||
node?.flowNodeType &&
|
||||
SETTING_ON_ERROR_NODES_CONFIG[node.flowNodeType]?.timeout
|
||||
) {
|
||||
timeoutConfig = SETTING_ON_ERROR_NODES_CONFIG[node.flowNodeType].timeout;
|
||||
}
|
||||
|
||||
return {
|
||||
...timeoutConfig,
|
||||
min: SETTING_ON_ERROR_MIN_TIMEOUT,
|
||||
disabled: isLocalPlugin(node),
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type ViewVariableTreeNode } from '@coze-workflow/base';
|
||||
|
||||
import { ERROR_BODY_NAME, IS_SUCCESS_NAME } from '../constants';
|
||||
import { generateErrorBodyMeta, generateIsSuccessMeta } from './generate-meta';
|
||||
|
||||
const settingOnErrorNames = isSettingOnErrorV2 => [
|
||||
ERROR_BODY_NAME,
|
||||
...(isSettingOnErrorV2 ? [IS_SUCCESS_NAME] : []),
|
||||
];
|
||||
|
||||
const excludeFn = isSettingOnErrorV2 => v =>
|
||||
!settingOnErrorNames(isSettingOnErrorV2).includes(v.name);
|
||||
|
||||
const includeFn = isSettingOnErrorV2 => v =>
|
||||
settingOnErrorNames(isSettingOnErrorV2).includes(v.name);
|
||||
|
||||
/**
|
||||
* 向 output 中添加/剔除 errorBody
|
||||
*/
|
||||
export const getOutputsWithErrorBody = ({
|
||||
value,
|
||||
isBatch,
|
||||
isOpen,
|
||||
isSettingOnErrorV2,
|
||||
}: {
|
||||
value?: ViewVariableTreeNode[];
|
||||
isBatch: boolean;
|
||||
isOpen: boolean;
|
||||
isSettingOnErrorV2?: boolean;
|
||||
}) => {
|
||||
if (!value) {
|
||||
return value;
|
||||
}
|
||||
// 添加 errorBody
|
||||
if (isOpen) {
|
||||
// batch 模式下,在第一层的 children 里追加 errorBody
|
||||
if (isBatch) {
|
||||
return [
|
||||
{
|
||||
...value[0],
|
||||
children: [
|
||||
...(value[0]?.children ?? []).filter(excludeFn(isSettingOnErrorV2)),
|
||||
generateErrorBodyMeta(),
|
||||
...(isSettingOnErrorV2 ? [generateIsSuccessMeta()] : []),
|
||||
],
|
||||
},
|
||||
];
|
||||
// single 模式下,在第一层追加 errorBody
|
||||
} else {
|
||||
return [
|
||||
...(value ?? []).filter(excludeFn(isSettingOnErrorV2)),
|
||||
generateErrorBodyMeta(),
|
||||
...(isSettingOnErrorV2 ? [generateIsSuccessMeta()] : []),
|
||||
];
|
||||
}
|
||||
// 剔除 errorBody
|
||||
} else {
|
||||
// batch 模式下,从第一层的 children 中剔除
|
||||
if (isBatch) {
|
||||
const [one, ...rest] = value;
|
||||
return [
|
||||
{
|
||||
...one,
|
||||
children: [
|
||||
...(one?.children ?? []).filter(excludeFn(isSettingOnErrorV2)),
|
||||
],
|
||||
},
|
||||
...rest,
|
||||
];
|
||||
// single 模式下,从第一层的 children 中剔除
|
||||
} else {
|
||||
return [...(value ?? []).filter(excludeFn(isSettingOnErrorV2))];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* output 属性排序,保证 errorBody 在最下面
|
||||
*/
|
||||
export const sortErrorBody = ({
|
||||
value,
|
||||
isBatch,
|
||||
isSettingOnErrorV2,
|
||||
}: {
|
||||
value?: ViewVariableTreeNode[];
|
||||
isBatch: boolean;
|
||||
isSettingOnErrorV2?: boolean;
|
||||
}) => {
|
||||
if (!value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (isBatch) {
|
||||
const [one, ...rest] = value;
|
||||
return [
|
||||
{
|
||||
...one,
|
||||
children: [
|
||||
...(one?.children ?? []).filter(excludeFn(isSettingOnErrorV2)),
|
||||
...(one?.children ?? []).filter(includeFn(isSettingOnErrorV2)),
|
||||
],
|
||||
},
|
||||
...rest,
|
||||
];
|
||||
}
|
||||
return [
|
||||
...value.filter(excludeFn(isSettingOnErrorV2)),
|
||||
...value.filter(includeFn(isSettingOnErrorV2)),
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* 把 value 中的 errorBody 删除掉
|
||||
*/
|
||||
export const getExcludeErrorBody = ({
|
||||
value,
|
||||
isBatch,
|
||||
isSettingOnErrorV2,
|
||||
}: {
|
||||
value?: ViewVariableTreeNode[];
|
||||
isBatch: boolean;
|
||||
isSettingOnErrorV2?: boolean;
|
||||
}) =>
|
||||
getOutputsWithErrorBody({
|
||||
value,
|
||||
isBatch,
|
||||
isOpen: false,
|
||||
isSettingOnErrorV2,
|
||||
});
|
||||
Reference in New Issue
Block a user