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, webhook_callback_url: values.webhookCallbackUrl,
proxy_location: values.proxyLocation, proxy_location: values.proxyLocation,
workflow_definition: { workflow_definition: {
version: 2,
parameters: [ parameters: [
{ {
parameter_type: "workflow", parameter_type: "workflow",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1908,6 +1908,43 @@ function convertParametersToParameterYAML(
.filter(Boolean); .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( function convertBlocksToBlockYAML(
blocks: Array<WorkflowBlock>, blocks: Array<WorkflowBlock>,
): Array<BlockYAML> { ): Array<BlockYAML> {
@@ -1915,6 +1952,7 @@ function convertBlocksToBlockYAML(
const base = { const base = {
label: block.label, label: block.label,
continue_on_failure: block.continue_on_failure, continue_on_failure: block.continue_on_failure,
next_block_label: block.next_block_label,
}; };
switch (block.block_type) { switch (block.block_type) {
case "task": { case "task": {
@@ -2216,6 +2254,7 @@ function convertBlocksToBlockYAML(
} }
function convert(workflow: WorkflowApiResponse): WorkflowCreateYAMLRequest { function convert(workflow: WorkflowApiResponse): WorkflowCreateYAMLRequest {
const workflowDefinitionVersion = workflow.workflow_definition.version ?? 1;
const userParameters = workflow.workflow_definition.parameters.filter( const userParameters = workflow.workflow_definition.parameters.filter(
(parameter) => parameter.parameter_type !== WorkflowParameterTypes.Output, (parameter) => parameter.parameter_type !== WorkflowParameterTypes.Output,
); );
@@ -2230,6 +2269,7 @@ function convert(workflow: WorkflowApiResponse): WorkflowCreateYAMLRequest {
max_screenshot_scrolls: workflow.max_screenshot_scrolls, max_screenshot_scrolls: workflow.max_screenshot_scrolls,
extra_http_headers: workflow.extra_http_headers, extra_http_headers: workflow.extra_http_headers,
workflow_definition: { workflow_definition: {
version: workflowDefinitionVersion,
parameters: convertParametersToParameterYAML(userParameters), parameters: convertParametersToParameterYAML(userParameters),
blocks: convertBlocksToBlockYAML(workflow.workflow_definition.blocks), blocks: convertBlocksToBlockYAML(workflow.workflow_definition.blocks),
}, },

View File

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

View File

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

View File

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