windmill-yaml-validator
Version:
YAML validator for Windmill flow, schedule, and trigger files
1,798 lines • 82 kB
JSON
{
"openapi": "3.0.3",
"info": {
"version": "1.775.2",
"title": "OpenFlow Spec",
"contact": {
"name": "Ruben Fiszel",
"email": "ruben@windmill.dev",
"url": "https://windmill.dev"
},
"license": {
"name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"paths": {},
"externalDocs": {
"description": "documentation portal",
"url": "https://windmill.dev"
},
"components": {
"schemas": {
"OpenFlow": {
"type": "object",
"description": "Top-level flow definition containing metadata, configuration, and the flow structure",
"properties": {
"summary": {
"type": "string",
"description": "Short description of what this flow does"
},
"description": {
"type": "string",
"description": "Detailed documentation for this flow"
},
"value": {
"$ref": "#/components/schemas/FlowValue"
},
"schema": {
"type": "object",
"description": "JSON Schema for flow inputs. Use this to define input parameters, their types, defaults, and validation. For resource inputs, set type to 'object' and format to 'resource-<type>' (e.g., 'resource-stripe')"
},
"on_behalf_of_email": {
"type": "string",
"description": "The flow will be run with the permissions of the user with this email."
}
},
"required": [
"summary",
"value"
]
},
"FlowValue": {
"type": "object",
"description": "The flow structure containing modules and optional preprocessor/failure handlers",
"properties": {
"modules": {
"type": "array",
"description": "Array of steps that execute in sequence. Each step can be a script, subflow, loop, or branch",
"items": {
"$ref": "#/components/schemas/FlowModule"
}
},
"failure_module": {
"description": "Special module that executes when the flow fails. Receives error object with message, name, stack, and step_id. Must have id 'failure'. Only supports script/rawscript types",
"$ref": "#/components/schemas/FlowModule"
},
"preprocessor_module": {
"description": "Special module that runs before the first step on external triggers. Must have id 'preprocessor'. Only supports script/rawscript types. Cannot reference other step results",
"$ref": "#/components/schemas/FlowModule"
},
"same_worker": {
"type": "boolean",
"description": "If true, all steps run on the same worker for better performance"
},
"preserve_step_tags": {
"type": "boolean",
"description": "If true and the flow runs on a custom worker tag, steps that declare their own non-empty tag run on it instead of inheriting the flow tag. Steps without their own tag still inherit the flow tag."
},
"concurrent_limit": {
"type": "number",
"description": "Maximum number of concurrent executions of this flow"
},
"concurrency_key": {
"type": "string",
"description": "Expression to group concurrent executions (e.g., by user ID)"
},
"concurrency_time_window_s": {
"type": "number",
"description": "Time window in seconds for concurrent_limit"
},
"debounce_delay_s": {
"type": "integer",
"description": "Delay in seconds to debounce flow executions"
},
"debounce_key": {
"type": "string",
"description": "Expression to group debounced executions"
},
"debounce_args_to_accumulate": {
"type": "array",
"description": "Arguments to accumulate across debounced executions",
"items": {
"type": "string"
}
},
"max_total_debouncing_time": {
"type": "integer",
"description": "Maximum total time in seconds that a job can be debounced"
},
"max_total_debounces_amount": {
"type": "integer",
"description": "Maximum number of times a job can be debounced"
},
"skip_expr": {
"type": "string",
"description": "JavaScript expression to conditionally skip the entire flow"
},
"cache_ttl": {
"type": "number",
"description": "Cache duration in seconds for flow results"
},
"cache_ignore_s3_path": {
"type": "boolean"
},
"delete_after_secs": {
"type": "integer",
"description": "If set, delete the flow job's args, result and logs after this many seconds following job completion"
},
"flow_env": {
"type": "object",
"description": "Environment variables available to all steps. Values can be strings, JSON values, or special references: '$var:path' (workspace variable) or '$res:path' (resource).",
"additionalProperties": {}
},
"priority": {
"type": "number",
"description": "Execution priority (higher numbers run first)"
},
"early_return": {
"type": "string",
"description": "JavaScript expression to return early from the flow"
},
"chat_input_enabled": {
"type": "boolean",
"description": "Whether this flow accepts chat-style input"
},
"notes": {
"type": "array",
"description": "Sticky notes attached to the flow",
"items": {
"$ref": "#/components/schemas/FlowNote"
}
},
"groups": {
"type": "array",
"description": "Semantic groups of modules for organizational purposes",
"items": {
"$ref": "#/components/schemas/FlowGroup"
}
}
},
"required": [
"modules"
]
},
"Retry": {
"type": "object",
"description": "Retry configuration for failed module executions",
"properties": {
"constant": {
"type": "object",
"description": "Retry with constant delay between attempts",
"properties": {
"attempts": {
"type": "integer",
"description": "Number of retry attempts"
},
"seconds": {
"type": "integer",
"description": "Seconds to wait between retries"
}
}
},
"exponential": {
"type": "object",
"description": "Retry with exponential backoff (delay doubles each time)",
"properties": {
"attempts": {
"type": "integer",
"description": "Number of retry attempts"
},
"multiplier": {
"type": "integer",
"description": "Multiplier for exponential backoff"
},
"seconds": {
"type": "integer",
"minimum": 1,
"description": "Initial delay in seconds"
},
"random_factor": {
"type": "integer",
"minimum": 0,
"maximum": 100,
"description": "Random jitter percentage (0-100) to avoid thundering herd"
}
}
},
"retry_if": {
"$ref": "#/components/schemas/RetryIf"
}
}
},
"FlowNote": {
"type": "object",
"description": "A sticky note attached to a flow for documentation and annotation",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the note"
},
"text": {
"type": "string",
"description": "Content of the note"
},
"position": {
"type": "object",
"description": "Position of the note in the flow editor",
"properties": {
"x": {
"type": "number",
"description": "X coordinate"
},
"y": {
"type": "number",
"description": "Y coordinate"
}
},
"required": [
"x",
"y"
]
},
"size": {
"type": "object",
"description": "Size of the note in the flow editor",
"properties": {
"width": {
"type": "number",
"description": "Width in pixels"
},
"height": {
"type": "number",
"description": "Height in pixels"
}
},
"required": [
"width",
"height"
]
},
"color": {
"type": "string",
"description": "Color of the note (e.g., \"yellow\", \"#ffff00\")"
},
"type": {
"type": "string",
"enum": [
"free",
"group"
],
"description": "Type of note - 'free' for standalone notes, 'group' for notes that group other nodes"
},
"locked": {
"type": "boolean",
"default": false,
"description": "Whether the note is locked and cannot be edited or moved"
},
"contained_node_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "For group notes, the IDs of nodes contained within this group"
}
},
"required": [
"id",
"text",
"color",
"type"
]
},
"FlowGroup": {
"type": "object",
"description": "A semantic group of flow modules for organizational purposes. Does not affect execution — modules remain in their original position in the flow. Groups provide naming and collapsibility in the editor. Members are computed dynamically from all nodes on paths between start_id and end_id.",
"properties": {
"summary": {
"type": "string",
"description": "Display name for this group"
},
"note": {
"type": "string",
"description": "Markdown note shown below the group header"
},
"autocollapse": {
"type": "boolean",
"default": false,
"description": "If true, this group is collapsed by default in the flow editor. UI hint only."
},
"start_id": {
"type": "string",
"description": "ID of the first flow module in this group (topological entry point)"
},
"end_id": {
"type": "string",
"description": "ID of the last flow module in this group (topological exit point)"
},
"color": {
"type": "string",
"description": "Color for the group in the flow editor"
}
},
"required": [
"start_id",
"end_id"
]
},
"RetryIf": {
"type": "object",
"description": "Conditional retry based on error or result",
"properties": {
"expr": {
"type": "string",
"description": "JavaScript expression that returns true to retry. Has access to 'result' and 'error' variables"
}
},
"required": [
"expr"
]
},
"StopAfterIf": {
"type": "object",
"description": "Early termination condition for a module",
"properties": {
"skip_if_stopped": {
"type": "boolean",
"description": "If true, following steps are skipped when this condition triggers"
},
"expr": {
"type": "string",
"description": "JavaScript expression evaluated after the module runs. Can use 'result' (step's result) or 'flow_input'. Return true to stop"
},
"error_message": {
"type": "string",
"nullable": true,
"description": "Custom error message when stopping with an error. Mutually exclusive with skip_if_stopped. If set to a non-empty string, the flow stops with this error. If empty string, a default error message is used. If null or omitted, no error is raised."
},
"error_include_result": {
"type": "boolean",
"description": "When stopping with an error (error_message set), embed the stopping step's own result inside the raised error object (as error.result) instead of discarding it. The top-level result stays { error }. Defaults to false."
}
},
"required": [
"expr"
]
},
"FlowModule": {
"type": "object",
"description": "A single step in a flow. Can be a script, subflow, loop, or branch",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this step. Used to reference results via 'results.step_id'. Must be a valid identifier (alphanumeric, underscore, hyphen)"
},
"value": {
"$ref": "#/components/schemas/FlowModuleValue"
},
"stop_after_if": {
"description": "Early termination condition evaluated after this step completes",
"$ref": "#/components/schemas/StopAfterIf"
},
"stop_after_all_iters_if": {
"description": "For loops only - early termination condition evaluated after all iterations complete",
"$ref": "#/components/schemas/StopAfterIf"
},
"skip_if": {
"type": "object",
"description": "Conditionally skip this step based on previous results or flow inputs",
"properties": {
"expr": {
"type": "string",
"description": "JavaScript expression that returns true to skip. Can use 'flow_input' or 'results.<step_id>'"
}
},
"required": [
"expr"
]
},
"sleep": {
"description": "Delay before executing this step (in seconds or as expression)",
"$ref": "#/components/schemas/InputTransform"
},
"cache_ttl": {
"type": "number",
"description": "Cache duration in seconds for this step's results"
},
"cache_ignore_s3_path": {
"type": "boolean"
},
"timeout": {
"description": "Maximum execution time in seconds (static value or expression)",
"$ref": "#/components/schemas/InputTransform"
},
"delete_after_secs": {
"type": "integer",
"description": "If set, delete the step's args, result and logs after this many seconds following job completion"
},
"summary": {
"type": "string",
"description": "Short description of what this step does"
},
"mock": {
"type": "object",
"description": "Mock configuration for testing without executing the actual step",
"properties": {
"enabled": {
"type": "boolean",
"description": "If true, return mock value instead of executing"
},
"return_value": {
"description": "Value to return when mocked"
}
}
},
"suspend": {
"type": "object",
"description": "Configuration for approval/resume steps that wait for user input",
"properties": {
"required_events": {
"type": "integer",
"description": "Number of approvals required before continuing"
},
"timeout": {
"type": "integer",
"description": "Timeout in seconds before auto-continuing or canceling"
},
"resume_form": {
"type": "object",
"description": "Form schema for collecting input when resuming",
"properties": {
"schema": {
"type": "object",
"description": "JSON Schema for the resume form"
}
}
},
"user_auth_required": {
"type": "boolean",
"description": "If true, only authenticated users can approve"
},
"user_groups_required": {
"description": "Expression or list of groups that can approve",
"$ref": "#/components/schemas/InputTransform"
},
"self_approval_disabled": {
"type": "boolean",
"description": "If true, the user who started the flow cannot approve"
},
"hide_cancel": {
"type": "boolean",
"description": "If true, hide the cancel button on the approval form"
},
"continue_on_disapprove_timeout": {
"type": "boolean",
"description": "If true, continue flow on timeout instead of canceling"
}
}
},
"priority": {
"type": "number",
"description": "Execution priority for this step (higher numbers run first)"
},
"continue_on_error": {
"type": "boolean",
"description": "If true, flow continues even if this step fails"
},
"retry": {
"description": "Retry configuration if this step fails",
"$ref": "#/components/schemas/Retry"
},
"debouncing": {
"description": "Debounce configuration for this step (EE only)",
"type": "object",
"properties": {
"debounce_delay_s": {
"type": "integer",
"description": "Delay in seconds to debounce this step's executions across flow runs"
},
"debounce_key": {
"type": "string",
"description": "Expression to group debounced executions. Supports $workspace and $args[name]. Default: $workspace/flow/<flow_path>-<step_id>"
},
"debounce_args_to_accumulate": {
"type": "array",
"description": "Array-type arguments to accumulate across debounced executions",
"items": {
"type": "string"
}
},
"max_total_debouncing_time": {
"type": "integer",
"description": "Maximum total time in seconds before forced execution"
},
"max_total_debounces_amount": {
"type": "integer",
"description": "Maximum number of debounces before forced execution"
}
}
}
},
"required": [
"value",
"id"
]
},
"InputTransform": {
"description": "Maps input parameters for a step. Can be a static value or a JavaScript expression that references previous results or flow inputs",
"oneOf": [
{
"$ref": "#/components/schemas/StaticTransform"
},
{
"$ref": "#/components/schemas/JavascriptTransform"
},
{
"$ref": "#/components/schemas/AiTransform"
}
],
"discriminator": {
"propertyName": "type"
}
},
"StaticTransform": {
"type": "object",
"description": "Static value passed directly to the step. Use for hardcoded values or resource references like '$res:path/to/resource'",
"properties": {
"value": {
"description": "The static value. For resources, use format '$res:path/to/resource'"
},
"type": {
"type": "string",
"enum": [
"static"
]
}
},
"required": [
"type"
]
},
"JavascriptTransform": {
"type": "object",
"description": "JavaScript expression evaluated at runtime. Can reference previous step results via 'results.step_id' or flow inputs via 'flow_input.property'. Inside for loops, use 'flow_input.iter.value' for the current iteration value (in while loops it equals 'flow_input.iter.index')",
"properties": {
"expr": {
"type": "string",
"description": "JavaScript expression returning the value. Available variables - results (object with all previous step results), flow_input (flow inputs), flow_input.iter (in loops)"
},
"type": {
"type": "string",
"enum": [
"javascript"
]
}
},
"required": [
"expr",
"type"
]
},
"AiTransform": {
"type": "object",
"description": "Value resolved by the AI runtime for this input. The AI engine decides how to satisfy the parameter.",
"properties": {
"type": {
"type": "string",
"enum": [
"ai"
]
}
},
"required": [
"type"
]
},
"AIProviderKind": {
"type": "string",
"description": "Supported AI provider types",
"enum": [
"openai",
"azure_openai",
"azure_foundry",
"anthropic",
"mistral",
"deepseek",
"googleai",
"groq",
"openrouter",
"togetherai",
"customai",
"aws_bedrock"
]
},
"ProviderConfig": {
"type": "object",
"description": "Complete AI provider configuration with resource reference and model selection",
"properties": {
"kind": {
"$ref": "#/components/schemas/AIProviderKind"
},
"resource": {
"type": "string",
"description": "Resource reference in format '$res:{resource_path}' pointing to provider credentials"
},
"model": {
"type": "string",
"description": "Model identifier (e.g., 'gpt-4', 'claude-3-opus-20240229', 'gemini-pro')"
},
"reasoning_effort": {
"type": "string",
"description": "Provider-native reasoning effort token (e.g. 'low', 'high', 'none') for models that support extended thinking. Optional; unset leaves the provider default."
}
},
"required": [
"kind",
"resource",
"model"
]
},
"StaticProviderTransform": {
"type": "object",
"description": "Static provider configuration passed directly to the AI agent",
"properties": {
"value": {
"$ref": "#/components/schemas/ProviderConfig"
},
"type": {
"type": "string",
"enum": [
"static"
]
}
},
"required": [
"type",
"value"
]
},
"ProviderTransform": {
"description": "Provider configuration - can be static (ProviderConfig), JavaScript expression, or AI-determined",
"oneOf": [
{
"$ref": "#/components/schemas/StaticProviderTransform"
},
{
"$ref": "#/components/schemas/JavascriptTransform"
},
{
"$ref": "#/components/schemas/AiTransform"
}
],
"discriminator": {
"propertyName": "type"
}
},
"MemoryOff": {
"type": "object",
"description": "No conversation memory/context",
"properties": {
"kind": {
"type": "string",
"enum": [
"off"
]
}
},
"required": [
"kind"
]
},
"MemoryAuto": {
"type": "object",
"description": "Automatic context management",
"properties": {
"kind": {
"type": "string",
"enum": [
"auto"
]
},
"context_length": {
"type": "integer",
"description": "Maximum number of messages to retain in context"
},
"memory_id": {
"type": "string",
"description": "Identifier for persistent memory across agent invocations"
}
},
"required": [
"kind"
]
},
"MemoryMessage": {
"type": "object",
"description": "A single message in conversation history",
"properties": {
"role": {
"type": "string",
"enum": [
"user",
"assistant",
"system"
]
},
"content": {
"type": "string"
}
},
"required": [
"role",
"content"
]
},
"MemoryManual": {
"type": "object",
"description": "Explicit message history",
"properties": {
"kind": {
"type": "string",
"enum": [
"manual"
]
},
"messages": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MemoryMessage"
}
}
},
"required": [
"kind",
"messages"
]
},
"MemoryConfig": {
"description": "Conversation memory configuration",
"oneOf": [
{
"$ref": "#/components/schemas/MemoryOff"
},
{
"$ref": "#/components/schemas/MemoryAuto"
},
{
"$ref": "#/components/schemas/MemoryManual"
}
],
"discriminator": {
"propertyName": "kind"
}
},
"StaticMemoryTransform": {
"type": "object",
"description": "Static memory configuration passed directly to the AI agent",
"properties": {
"value": {
"$ref": "#/components/schemas/MemoryConfig"
},
"type": {
"type": "string",
"enum": [
"static"
]
}
},
"required": [
"type",
"value"
]
},
"MemoryTransform": {
"description": "Memory configuration - can be static (MemoryConfig), JavaScript expression, or AI-determined",
"oneOf": [
{
"$ref": "#/components/schemas/StaticMemoryTransform"
},
{
"$ref": "#/components/schemas/JavascriptTransform"
},
{
"$ref": "#/components/schemas/AiTransform"
}
],
"discriminator": {
"propertyName": "type"
}
},
"FlowModuleValue": {
"description": "The actual implementation of a flow step. Can be a script (inline or referenced), subflow, loop, branch, or special module type",
"oneOf": [
{
"$ref": "#/components/schemas/RawScript"
},
{
"$ref": "#/components/schemas/PathScript"
},
{
"$ref": "#/components/schemas/PathFlow"
},
{
"$ref": "#/components/schemas/ForloopFlow"
},
{
"$ref": "#/components/schemas/WhileloopFlow"
},
{
"$ref": "#/components/schemas/BranchOne"
},
{
"$ref": "#/components/schemas/BranchAll"
},
{
"$ref": "#/components/schemas/Identity"
},
{
"$ref": "#/components/schemas/AiAgent"
}
],
"discriminator": {
"propertyName": "type"
}
},
"RawScript": {
"type": "object",
"description": "Inline script with code defined directly in the flow. Use 'bun' as default language if unspecified. The script receives arguments from input_transforms",
"properties": {
"input_transforms": {
"type": "object",
"description": "Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments",
"additionalProperties": {
"$ref": "#/components/schemas/InputTransform"
}
},
"content": {
"type": "string",
"description": "The script source code. Should export a 'main' function"
},
"language": {
"type": "string",
"description": "Programming language for this script",
"enum": [
"deno",
"bun",
"bunnative",
"python3",
"go",
"bash",
"powershell",
"postgresql",
"mysql",
"bigquery",
"snowflake",
"mssql",
"oracledb",
"graphql",
"nativets",
"php",
"rust",
"ansible",
"csharp",
"nu",
"java",
"ruby",
"rlang",
"duckdb"
]
},
"path": {
"type": "string",
"description": "Optional path for saving this script"
},
"lock": {
"type": "string",
"description": "Lock file content for dependencies"
},
"type": {
"type": "string",
"enum": [
"rawscript"
]
},
"tag": {
"type": "string",
"description": "Worker group tag for execution routing"
},
"concurrent_limit": {
"type": "number",
"description": "Maximum concurrent executions of this script"
},
"concurrency_time_window_s": {
"type": "number",
"description": "Time window for concurrent_limit"
},
"custom_concurrency_key": {
"type": "string",
"description": "Custom key for grouping concurrent executions"
},
"is_trigger": {
"type": "boolean",
"description": "If true, this script is a trigger that can start the flow"
},
"assets": {
"type": "array",
"description": "External resources this script accesses (S3 objects, resources, etc.)",
"items": {
"type": "object",
"required": [
"path",
"kind"
],
"properties": {
"path": {
"type": "string",
"description": "Path to the asset"
},
"kind": {
"type": "string",
"description": "Type of asset",
"enum": [
"s3object",
"resource",
"ducklake",
"datatable",
"volume"
]
},
"access_type": {
"type": "string",
"nullable": true,
"description": "Access level for this asset",
"enum": [
"r",
"w",
"rw",
null
]
},
"alt_access_type": {
"type": "string",
"nullable": true,
"description": "Alternative access level",
"enum": [
"r",
"w",
"rw",
null
]
}
}
}
}
},
"required": [
"type",
"content",
"language",
"input_transforms"
]
},
"PathScript": {
"type": "object",
"description": "Reference to an existing script by path. Use this when calling a previously saved script instead of writing inline code",
"properties": {
"input_transforms": {
"type": "object",
"description": "Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments",
"additionalProperties": {
"$ref": "#/components/schemas/InputTransform"
}
},
"path": {
"type": "string",
"description": "Path to the script in the workspace (e.g., 'f/scripts/send_email')"
},
"hash": {
"type": "string",
"description": "Optional specific version hash of the script to use"
},
"type": {
"type": "string",
"enum": [
"script"
]
},
"tag_override": {
"type": "string",
"description": "Override the script's default worker group tag"
},
"is_trigger": {
"type": "boolean",
"description": "If true, this script is a trigger that can start the flow"
}
},
"required": [
"type",
"path",
"input_transforms"
]
},
"PathFlow": {
"type": "object",
"description": "Reference to an existing flow by path. Use this to call another flow as a subflow",
"properties": {
"input_transforms": {
"type": "object",
"description": "Map of parameter names to their values (static or JavaScript expressions). These become the subflow's input arguments",
"additionalProperties": {
"$ref": "#/components/schemas/InputTransform"
}
},
"path": {
"type": "string",
"description": "Path to the flow in the workspace (e.g., 'f/flows/process_user')"
},
"type": {
"type": "string",
"enum": [
"flow"
]
}
},
"required": [
"type",
"path",
"input_transforms"
]
},
"ForloopFlow": {
"type": "object",
"description": "Executes nested modules in a loop over an iterator. Inside the loop, use 'flow_input.iter.value' to access the current iteration value, and 'flow_input.iter.index' for the index. Supports parallel execution for better performance on I/O-bound operations",
"properties": {
"modules": {
"type": "array",
"description": "Steps to execute for each iteration. These can reference the iteration value via 'flow_input.iter.value'",
"items": {
"$ref": "#/components/schemas/FlowModule"
}
},
"iterator": {
"description": "JavaScript expression that returns an array to iterate over. Can reference 'results.step_id' or 'flow_input'",
"$ref": "#/components/schemas/InputTransform"
},
"skip_failures": {
"type": "boolean",
"description": "If true, iteration failures don't stop the loop. Failed iterations return null"
},
"type": {
"type": "string",
"enum": [
"forloopflow"
]
},
"parallel": {
"type": "boolean",
"description": "If true, iterations run concurrently (faster for I/O-bound operations). Use with parallelism to control concurrency"
},
"parallelism": {
"description": "Maximum number of concurrent iterations when parallel=true. Limits resource usage. Can be static number or expression",
"$ref": "#/components/schemas/InputTransform"
},
"squash": {
"type": "boolean"
}
},
"required": [
"modules",
"iterator",
"skip_failures",
"type"
]
},
"WhileloopFlow": {
"type": "object",
"description": "Executes nested modules repeatedly until stopped. The implicit iterator is the iteration counter, so 'flow_input.iter.value' equals 'flow_input.iter.index' (0, 1, 2, ...) and never carries state. To carry state across iterations, a step reads its own previous-iteration result via 'results.<its_own_id>' with a first-iteration fallback - the loop's stop_after_if must then be on that inner step (a plain single-step body with stop_after_if on the loop module does not resolve 'results' across iterations and never terminates); plain counters can instead be derived from 'flow_input.iter.index', which works in every configuration. stop_after_if is evaluated after each iteration - on the loop module 'result' is the last iteration's result",
"properties": {
"modules": {
"type": "array",
"description": "Steps to execute in each iteration",
"items": {
"$ref": "#/components/schemas/FlowModule"
}
},
"skip_failures": {
"type": "boolean",
"description": "If true, iteration failures don't stop the loop. Failed iterations return null"
},
"type": {
"type": "string",
"enum": [
"whileloopflow"
]
},
"parallel": {
"type": "boolean",
"description": "If true, iterations run concurrently (use with caution in while loops)"
},
"parallelism": {
"description": "Maximum number of concurrent iterations when parallel=true",
"$ref": "#/components/schemas/InputTransform"
},
"squash": {
"type": "boolean"
}
},
"required": [
"modules",
"skip_failures",
"type"
]
},
"BranchOne": {
"type": "object",
"description": "Conditional branching where only the first matching branch executes. Branches are evaluated in order, and the first one with a true expression runs. If no branches match, the default branch executes",
"properties": {
"branches": {
"type": "array",
"description": "Array of branches to evaluate in order. The first branch with expr evaluating to true executes",
"items": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "Short description of this branch condition"
},
"expr": {
"type": "string",
"description": "JavaScript expression that returns boolean. Can use 'results.step_id' or 'flow_input'. First true expr wins"
},
"modules": {
"type": "array",
"description": "Steps to execute if this branch's expr is true",
"items": {
"$ref": "#/components/schemas/FlowModule"
}
}
},
"required": [
"modules",
"expr"
]
}
},
"default": {
"type": "array",
"description": "Steps to execute if no branch expressions match",
"items": {
"$ref": "#/components/schemas/FlowModule"
}
},
"type": {
"type": "string",
"enum": [
"branchone"
]
}
},
"required": [
"branches",
"default",
"type"
]
},
"BranchAll": {
"type": "object",
"description": "Parallel branching where all branches execute simultaneously. Unlike BranchOne, all branches run regardless of conditions. Useful for executing independent tasks concurrently",
"properties": {
"branches": {
"type": "array",
"description": "Array of branches that all execute (either in parallel or sequentially)",
"items": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "Short description of this branch's purpose"
},
"skip_failure": {
"type": "boolean",
"description": "If true, failure in this branch doesn't fail the entire flow"
},
"modules": {
"type": "array",
"description": "Steps to execute in this branch",
"items": {
"$ref": "#/components/schemas/FlowModule"
}
}
},
"required": [
"modules"
]
}
},
"type": {
"type": "string",
"enum": [
"branchall"
]
},
"parallel": {
"type": "boolean",
"description": "If true, all branches execute concurrently. If false, they execute sequentially"
}
},
"required": [
"branches",
"type"
]
},
"AgentTool": {
"type": "object",
"description": "A tool available to an AI agent. Can be a flow module or an external MCP (Model Context Protocol) tool",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this tool. Cannot contain spaces - use underscores instead (e.g., 'get_user_data' not 'get user data')"
},
"summary": {
"type": "string",
"description": "Short description of what this tool does (shown to the AI)"
},
"description": {
"type": "string",
"description": "Free-text description of the tool given to the AI to decide when and how to call it. Overrides the description auto-derived from the underlying script."
},
"value": {
"$ref": "#/components/schemas/ToolValue"
}
},
"required": [
"id",
"value"
]
},
"ToolValue": {
"description": "The implementation of a tool. Can be a flow module (script/flow) or an MCP tool reference",
"oneOf": [
{
"$ref": "#/components/schemas/FlowModuleTool"
},
{
"$ref": "#/components/schemas/McpToolValue"
},
{
"$ref": "#/components/schemas/WebsearchToolValue"
}
]
},
"FlowModuleTool": {
"description": "A tool implemented as a flow module (script, flow, etc.). The AI can call this like any other flow module",
"allOf": [
{
"type": "object",
"properties": {
"tool_type": {
"type": "string",
"enum": [
"flowmodule"
]
}
},
"required": [
"tool_type"
]
},
{
"$ref": "#/components/schemas/FlowModuleValue"
}
]
},
"WebsearchToolValue": {
"type": "object",
"description": "A tool implemented as a websearch tool. The AI can call this like any other websearch tool",
"properties": {
"tool_type": {
"type": "string",
"enum": [
"websearch"
]
}
},
"required": [
"tool_type"
]
},
"McpToolValue": {
"type": "object",
"description": "Reference to an external MCP (Model Context Protocol) tool. The AI can call tools from MCP servers",
"properties": {
"tool_type": {
"type": "string",
"enum": [
"mcp"
]
},
"resource_path": {
"type": "string",
"description": "Path to the MCP resource/server configuration"
},
"include_tools": {
"type": "array",
"description": "Whitelist of specific tools to include from this MCP server",
"items": {
"type": "string"
}
},
"exclude_tools": {
"type": "array",
"description": "Blacklist of tools to exclude from this MCP server",
"items": {
"type": "string"
}
}
},
"required": [
"tool_type",
"resource_path"
]
},
"AiAgent": {
"type": "object",
"description": "AI agent step that can use tools to accomplish tasks. The agent receives inputs and can call any of its configured tools to complete the task",
"properties": {
"input_transforms": {
"type": "object",
"description": "Input parameters for the AI agent mapped to their values",
"properties": {
"provider": {
"$ref": "#/components/schemas/ProviderTransform"
},
"output_type": {
"allOf": [
{
"$ref": "#/components/schemas/InputTransform"
}
],
"description": "Output format type.\nValid values: 'text' (default) - plain text response, 'image' - image generation\n"
},
"user_message": {
"allOf": [
{
"$ref": "#/components/schemas/InputTransform"
}
],
"description": "The user's prompt/message to the AI agent. Supports variable interpolation with flow.input syntax."
},
"system_prompt": {
"allOf": [
{
"$ref": "#/components/schemas/InputTransform"
}
],
"description": "System instructions that guide the AI's behavior, persona, and response style. Optional."
},
"streaming": {
"allOf": [
{
"$ref": "#/components/schemas/InputTransform"
}
],
"description": "Boolean. If true, stream the AI response incrementally.\nStreaming events include: token_delta, reasoning_token_delta, tool_call, tool_call_arguments, tool_execution, tool_result\n"
},
"memory": {
"$ref": "#/components/schemas/MemoryTransform"
},
"output_schema": {
"allOf": [
{
"$ref": "#/components/schemas/InputTransform"
}
],
"description": "JSON Schema object defining structured output format. Used when you need the AI to return data in a specific shape.\nSupports standard JSON Schema properties: type, properties, required, items, enum, pattern, minLength, maxLength, minimum, maximum, etc.\nExample: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' } }, required: ['name'] }\n"
},
"user_attachments": {
"allOf": [
{
"$ref": "#/components/schemas/InputTransform"
}
],
"description": "Array of file references (images or PDFs) for the AI agent.\nFormat: Array<{ bucket: string, key: string }> - S3 object references\nExample: [{ bucket: 'my-bucket', key: 'documents/report.pdf' }]\n"
},
"max_completion_tokens": {
"allOf": [
{
"$ref": "#/components/schemas/InputTransform"
}
],
"description": "Integer. Maximum number of tokens the AI will generate in its response.\nRange: 1 to 4,294,967,295. Typical values: 256-4096 for most use cases.\n"
},
"temperature": {
"allOf": [
{
"$ref": "#/components/schemas/InputTransform"
}
],
"description": "Float. Controls randomness/creativity of responses.\nRange: 0.0 to 2.0 (provider-dependent)\n- 0.0 = deterministic, focused responses\n- 0.7 = balanced (common default)\n- 1.0+ = more creative/random\n"
},
"max_iterations": {
"allOf": [
{
"$ref": "#/components/schemas/InputTransform"
}
],
"description": "Number. Limits how many times the agent can loop through reasoning and tool use.\nRange: 1-1000.\n"
}
},
"required": [
"user_message"
]
},
"tools": {
"type": "array",
"description": "Array of tools the agent can use. The agent decides which tools to call based on the task",
"items": {
"$ref": "#/components/schemas/AgentTool"
}
},
"type": {
"type": "string",
"enum": [
"aiagent"
]
},
"tag": {
"type": "string",
"description": "Worker group tag for execution routing. If not set, the AI agent step runs on the flow's tag (default `flow`)"
},
"omit_output_from_conversation": {
"type": "boolean",
"default": false,
"description": "If true, this AI agent step does not persist its assistant or tool messages to the flow conversation when chat mode is enabled."
},
"agent": {
"type": "string",
"description": "Path of a reusable `ai_agent` resource (hybrid linking). When set, the agent brain\nconfig (provider/model/system prompt/etc.) and tool set are resolved at runtime from\nthat resource; the module's input_transforms then only carry the flow-local inputs\n(user_message/user_attachments).\n"
},
"tool_inputs": {
"type": "object",
"description": "Host-local wiring for an agent's tool inputs, keyed by tool id then input key. Binds the\nreferenced agent's tools to this flow's context (flow_input/results) without mutating the\nshared resource; overlaid onto the tools' input_transforms at runtime — including when\n`agent` is unset, since a step forked for editing keeps these overrides until it is saved\nback or unlinked.\n",
"additionalProperties": {
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/InputTransform"
}
}
},
"parallel": {
"type": "boolean",
"description": "If true, the agent can execute multiple tool calls in parallel"
}
},
"required": [
"type",
"input_transforms"
]
},
"Identity": {
"type": "object",
"description": "Pass-through module that returns its input unchanged. Useful for flow structure or as a placeholder",
"properties": {
"type": {
"type": "string",
"enum": [
"identity"
]
},
"flow": {
"type": "boolean",
"description": "If true, marks this as a flow identity (special handling)"
}
},
"required": [
"type"
]
},
"FlowStatus": {
"type": "object",
"properties": {
"step": {
"type": "integer"
},
"modules": {
"type": "array",
"items": {
"$ref": "#/components/schemas/FlowStatusModule"
}
},
"user_states": {
"additionalProperties": true
},
"preprocessor_module": {
"allOf": [
{
"$ref": "#/components/schemas/FlowStatusModule"
}
]
},
"failure_module": {
"allOf": [
{
"$ref": "#/components/schemas/FlowStatusModule"
},
{
"type": "object",
"properties": {
"parent_module": {
"type": "string"
}
}
}
]
},
"retry": {
"type": "object",
"properties": {
"fail_count": {
"type": "integer"
},
"failed_jobs": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
}
}
},
"required": [
"step",
"modules",
"failure_module"
]
},
"FlowStatusModule": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"WaitingForPriorSteps",
"WaitingForEvents",
"WaitingForExecutor",
"InProgress",
"Success",
"Failure"
]
},
"id": {
"type": "string"
},
"job": {
"type": "string",
"format": "uuid"
},
"count": {
"type": "integer"
},
"progress": {
"type": "integer"
},
"iterator": {
"type": "object",
"properties": {
"index": {
"type": "integer"
},
"itered": {
"type": "array",
"items": {}
},
"itered_len": {
"type": "integer"
},
"args": {}
}
},
"flow_jobs": {
"type": "array",
"items": {
"type": "string"
}
},
"flow_jobs_success": {
"type": "array",
"items": {
"type": "boolean"
}
},
"flow_jobs_duration": {
"type": "object",
"properties": {
"started_at": {
"type": "array",
"items": {
"type": "string"
}
},
"duration_ms": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"branch_chosen": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"branch",
"default"
]
},
"branch": {
"type": "integer"
}
},
"required": [
"type"
]
},
"branchall": {
"type": "object",
"properties": {
"branch": {
"type": "integer"
},
"len": {
"type": "integer"
}
},
"required": [
"branch",
"len"
]
},
"approvers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"resume_id": {
"type": "integer"
},
"approver": {
"type": "string"
}
},
"required": [
"resume_id",
"approver"
]
}
},
"failed_retries": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"skipped": {
"type": "boolean"
},
"agent_actions": {
"type": "array",
"items": {
"type": "object",
"oneOf": [
{
"type": "object",
"properties": {
"job_id": {
"type": "string",
"format": "uuid"
},
"function_name": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"tool_call"
]
},
"module_id": {
"type": "string"
}
},
"required": [
"job_id",
"function_name",
"type",
"module_id"
]
},
{
"type": "object",
"properties": {
"call_id": {
"type": "string",
"format": "uuid"
},
"function_name": {
"type": "string"
},
"resource_path": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"mcp_tool_call"
]
},
"arguments": {
"type": "object"
}
},
"required": [
"call_id",
"function_name",
"resource_path",
"type"
]
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"web_search"
]
}
},
"required": [
"type"
]
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"message"
]
}
},
"required": [
"content",
"type"
]
}
]
}
},
"agent_actions_success": {
"type": "array",
"items": {
"type": "boolean"
}
}
},
"required": [
"type"
]
}
}
}
}