workflow definition version transition for skip if and future DAG support (#4012)

This commit is contained in:
Celal Zamanoglu
2025-11-22 05:04:45 +03:00
committed by GitHub
parent 335aa8f2df
commit 90f51bcacb
10 changed files with 60 additions and 2 deletions

View File

@@ -87,6 +87,7 @@ function createTaskTemplateRequestObject(values: SavedTaskFormValues) {
webhook_callback_url: values.webhookCallbackUrl,
proxy_location: values.proxyLocation,
workflow_definition: {
version: 2,
parameters: [
{
parameter_type: "workflow",

View File

@@ -30,6 +30,7 @@ function createEmptyTaskTemplate() {
webhook_callback_url: null,
proxy_location: "RESIDENTIAL",
workflow_definition: {
version: 2,
parameters: [
{
parameter_type: "workflow",

View File

@@ -54,6 +54,7 @@ function createTaskTemplateRequestObject(
webhook_callback_url: task.request.webhook_callback_url,
proxy_location: task.request.proxy_location,
workflow_definition: {
version: 2,
parameters: [
{
parameter_type: "workflow",

View File

@@ -65,6 +65,7 @@ const emptyWorkflowRequest: WorkflowCreateYAMLRequest = {
ai_fallback: true,
run_with: "agent",
workflow_definition: {
version: 2,
blocks: [],
parameters: [],
},

View File

@@ -8,6 +8,7 @@ const emptyWorkflowRequest: WorkflowCreateYAMLRequest = {
title: "New Workflow",
description: "",
workflow_definition: {
version: 2,
blocks: [],
parameters: [],
},

View File

@@ -84,6 +84,7 @@ import {
getWorkflowBlocks,
getWorkflowSettings,
layout,
upgradeWorkflowDefinitionToVersionTwo,
} from "./workflowEditorUtils";
import { getWorkflowErrors } from "./workflowEditorUtils";
import { toast } from "@/components/ui/use-toast";
@@ -360,6 +361,11 @@ function FlowRenderer({
const constructSaveData = useCallback((): WorkflowSaveData => {
const blocks = getWorkflowBlocks(nodes, edges);
const { blocks: upgradedBlocks, version: workflowDefinitionVersion } =
upgradeWorkflowDefinitionToVersionTwo(
blocks,
workflow.workflow_definition.version,
);
const settings = getWorkflowSettings(nodes);
const parametersInYAMLConvertibleJSON = convertToParametersYAML(parameters);
const filteredParameters = workflow.workflow_definition.parameters.filter(
@@ -377,7 +383,7 @@ function FlowRenderer({
// if there is an email node, we need to add the email aws secret parameters
const emailAwsSecretParameters = getAdditionalParametersForEmailBlock(
blocks,
upgradedBlocks,
overallParameters,
);
@@ -387,7 +393,8 @@ function FlowRenderer({
...parametersInYAMLConvertibleJSON,
...emailAwsSecretParameters,
],
blocks,
blocks: upgradedBlocks,
workflowDefinitionVersion,
title,
settings,
workflow,

View File

@@ -1908,6 +1908,43 @@ function convertParametersToParameterYAML(
.filter(Boolean);
}
function clone<T>(objectToClone: T): T {
return JSON.parse(JSON.stringify(objectToClone));
}
function assignSequentialNextBlockLabels(blocks: Array<BlockYAML>): void {
if (!blocks || blocks.length === 0) {
return;
}
for (let index = 0; index < blocks.length; index++) {
const block = blocks[index]!;
const nextBlock =
index < blocks.length - 1 ? blocks[index + 1]! : undefined;
block.next_block_label = nextBlock ? nextBlock.label : null;
if (block.block_type === "for_loop") {
const loopBlock = block as ForLoopBlockYAML;
assignSequentialNextBlockLabels(loopBlock.loop_blocks);
}
}
}
export function upgradeWorkflowDefinitionToVersionTwo(
blocks: Array<BlockYAML>,
currentVersion?: number | null,
): { blocks: Array<BlockYAML>; version: number } {
const clonedBlocks = clone(blocks);
const baseVersion = currentVersion ?? 1;
if (baseVersion <= 2) {
assignSequentialNextBlockLabels(clonedBlocks);
return { blocks: clonedBlocks, version: 2 };
}
return { blocks: clonedBlocks, version: baseVersion };
}
function convertBlocksToBlockYAML(
blocks: Array<WorkflowBlock>,
): Array<BlockYAML> {
@@ -1915,6 +1952,7 @@ function convertBlocksToBlockYAML(
const base = {
label: block.label,
continue_on_failure: block.continue_on_failure,
next_block_label: block.next_block_label,
};
switch (block.block_type) {
case "task": {
@@ -2216,6 +2254,7 @@ function convertBlocksToBlockYAML(
}
function convert(workflow: WorkflowApiResponse): WorkflowCreateYAMLRequest {
const workflowDefinitionVersion = workflow.workflow_definition.version ?? 1;
const userParameters = workflow.workflow_definition.parameters.filter(
(parameter) => parameter.parameter_type !== WorkflowParameterTypes.Output,
);
@@ -2230,6 +2269,7 @@ function convert(workflow: WorkflowApiResponse): WorkflowCreateYAMLRequest {
max_screenshot_scrolls: workflow.max_screenshot_scrolls,
extra_http_headers: workflow.extra_http_headers,
workflow_definition: {
version: workflowDefinitionVersion,
parameters: convertParametersToParameterYAML(userParameters),
blocks: convertBlocksToBlockYAML(workflow.workflow_definition.blocks),
},

View File

@@ -288,6 +288,7 @@ export type WorkflowBlockBase = {
output_parameter: OutputParameter;
continue_on_failure: boolean;
model: WorkflowModel | null;
next_block_label?: string | null;
};
export type TaskBlock = WorkflowBlockBase & {
@@ -522,6 +523,7 @@ export type HttpRequestBlock = WorkflowBlockBase & {
};
export type WorkflowDefinition = {
version?: number | null;
parameters: Array<Parameter>;
blocks: Array<WorkflowBlock>;
};

View File

@@ -24,6 +24,7 @@ export type WorkflowCreateYAMLRequest = {
};
export type WorkflowDefinitionYAML = {
version?: number | null;
parameters: Array<ParameterYAML>;
blocks: Array<BlockYAML>;
};
@@ -144,6 +145,7 @@ export type BlockYAMLBase = {
block_type: WorkflowBlockType;
label: string;
continue_on_failure?: boolean;
next_block_label?: string | null;
};
export type TaskBlockYAML = BlockYAMLBase & {

View File

@@ -19,6 +19,7 @@ import { WorkflowCreateYAMLRequest } from "@/routes/workflows/types/workflowYaml
type SaveData = {
parameters: Array<ParameterYAML>;
blocks: Array<BlockYAML>;
workflowDefinitionVersion: number;
title: string;
settings: WorkflowSettings;
workflow: WorkflowApiResponse;
@@ -139,6 +140,7 @@ const useWorkflowSave = (opts?: WorkflowSaveOpts) => {
cache_key: normalizedKey,
ai_fallback: saveData.settings.aiFallback ?? true,
workflow_definition: {
version: saveData.workflowDefinitionVersion,
parameters: saveData.parameters,
blocks: saveData.blocks,
},