diff --git a/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowParameterAddPanel.tsx b/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowParameterAddPanel.tsx index 623a8351..d8fbce86 100644 --- a/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowParameterAddPanel.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/panels/WorkflowParameterAddPanel.tsx @@ -59,6 +59,7 @@ function header(type: WorkflowEditorParameterType) { } function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) { + const reservedKeys = ["current_item", "current_value", "current_index"]; const isCloud = useContext(CloudContext); const [key, setKey] = useState(""); const [urlParameterKey, setUrlParameterKey] = useState(""); @@ -317,6 +318,14 @@ function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) { }); return; } + if (reservedKeys.includes(key)) { + toast({ + variant: "destructive", + title: "Failed to add parameter", + description: `${key} is reserved, please use another key`, + }); + return; + } if (type === "workflow") { if ( parameterType === "json" && diff --git a/skyvern/forge/sdk/workflow/models/block.py b/skyvern/forge/sdk/workflow/models/block.py index fb7817aa..9ddf6e46 100644 --- a/skyvern/forge/sdk/workflow/models/block.py +++ b/skyvern/forge/sdk/workflow/models/block.py @@ -198,6 +198,15 @@ class Block(BaseModel, abc.ABC): ) template_data[self.label] = block_reference_data + + # inject the forloop metadata as global variables + if "current_index" in block_reference_data: + template_data["current_index"] = block_reference_data["current_index"] + if "current_item" in block_reference_data: + template_data["current_item"] = block_reference_data["current_item"] + if "current_value" in block_reference_data: + template_data["current_value"] = block_reference_data["current_value"] + return template.render(template_data) @classmethod @@ -948,7 +957,9 @@ class ForLoopBlock(Block): metadata: BlockMetadata = { "current_index": loop_idx, "current_value": loop_over_value, + "current_item": loop_over_value, } + workflow_run_context.update_block_metadata(self.label, metadata) workflow_run_context.update_block_metadata(loop_block.label, metadata) original_loop_block = loop_block diff --git a/skyvern/forge/sdk/workflow/models/parameter.py b/skyvern/forge/sdk/workflow/models/parameter.py index 104b7872..3c59b3f2 100644 --- a/skyvern/forge/sdk/workflow/models/parameter.py +++ b/skyvern/forge/sdk/workflow/models/parameter.py @@ -8,6 +8,8 @@ from pydantic import BaseModel, ConfigDict, Field from skyvern.exceptions import InvalidWorkflowParameter +RESERVED_PARAMETER_KEYS = ["current_item", "current_value", "current_index"] + class ParameterType(StrEnum): WORKFLOW = "workflow" diff --git a/skyvern/forge/sdk/workflow/service.py b/skyvern/forge/sdk/workflow/service.py index 14314491..d7e6198b 100644 --- a/skyvern/forge/sdk/workflow/service.py +++ b/skyvern/forge/sdk/workflow/service.py @@ -61,6 +61,7 @@ from skyvern.forge.sdk.workflow.models.block import ( ) from skyvern.forge.sdk.workflow.models.parameter import ( PARAMETER_TYPE, + RESERVED_PARAMETER_KEYS, AWSSecretParameter, BitwardenCreditCardDataParameter, BitwardenLoginCredentialParameter, @@ -1450,6 +1451,12 @@ class WorkflowService: reserved_keys=output_parameter_keys, parameter_keys=parameter_keys ) + if any(key in RESERVED_PARAMETER_KEYS for key in parameter_keys): + raise WorkflowDefinitionHasReservedParameterKeys( + reserved_keys=RESERVED_PARAMETER_KEYS, + parameter_keys=parameter_keys, + ) + # Create output parameters for all blocks block_output_parameters = await WorkflowService._create_all_output_parameters_for_workflow( workflow_id=workflow.workflow_id,