Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions _data/navigation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ items:
- url: /flows/
title: Conditional Flows
items:
- url: /flows/variables/
title: Variables

- url: /flows/flows-legacy/
title: Legacy Flows

Expand Down
1 change: 1 addition & 0 deletions src/content/docs/flows/flow-migration-guide/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: Migration Guide
slug: 'flows/flow-migration-guide'
description: Migrate a Legacy Flow to a Conditional Flow — open the Migration Preview, review the side-by-side comparison and structural changes, run the migration, and verify the result.
---


Expand Down
1 change: 1 addition & 0 deletions src/content/docs/flows/flows-legacy/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: Legacy Flows
slug: 'flows/flows-legacy'
description: The Legacy Flow Builder — a sequential flow runner being replaced by Conditional Flows — how to build, schedule, and monitor legacy flows, and the planned migration.
redirect_from:
- /orchestrator/
- /orchestrator/design/
Expand Down
21 changes: 13 additions & 8 deletions src/content/docs/flows/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: Conditional Flows
slug: 'flows'
description: Build automated pipelines with Conditional Flows — phases and parallel tasks, IF/THEN conditions, variables, retries, delays, notifications, schedules, and run history.
redirect_from:
- /flows/conditional-flows/
---
Expand All @@ -13,7 +14,9 @@ Flows allow you to build automated data pipelines with conditional logic, branch

## Access Flows

Navigate to **Conditional Flows > Create Flow**. You'll land directly in the Builder where you can start creating your first flow. Use the plus icon (+) to add different types of actions such as components, conditions, variables, notifications, and more — all of which are explained in detail later in this documentation.
Navigate to **Conditional Flows > Create Flow**. You'll land directly in the **Builder** tab, where you can start creating your first flow; the other tabs — **All Runs**, **Schedules**, **Notifications**, and **Versions** — cover monitoring and automation and are explained later in this documentation.

Use the plus icon (+) on the canvas to add a task to a phase. The **Add Task** menu offers three task types: **Component**, **Notification**, and **Variable**. Conditions are not tasks — they control which phase runs next and are configured on the transitions between phases. <!-- TODO(human-review): confirm how conditions are added in the Builder (on the phase transition?) — the Add Task menu does not include them. -->

## Build the Flow

Expand All @@ -23,10 +26,10 @@ Navigate to **Conditional Flows > Create Flow**. You'll land directly in the Bui
- **Tasks within a phase** run in parallel.
- **After all tasks in a phase complete**, based on conditions it is determined which phase will be executed next.
- You can define **multiple condition rules** - only the first matched condition is executed.
- **How to end a flow:** You can stop a flow at any point using the End Flow option in the ELSE path of a conditional condition. This is especially useful when none of your IF conditions are met and you want to avoid continuing to another phase.
- **How to end a flow:** You can stop a flow at any point using the End Flow option in the ELSE path of a conditional condition. This is especially useful when none of your IF conditions are met and you want to avoid continuing to another phase. <!-- TODO(human-review): confirm the "End Flow in the ELSE path" mechanism and its exact UI label. -->

:::caution
If too many tasks are scheduled in a single phase, you may exceed the available [Storage job](/storage/jobs/) slots, causing delays in your flow's execution. Limiting the number of concurrent component jobs to 10 is recommended. The Keboola Support team can help you adjust parallel limits.
If too many tasks are scheduled in a single phase, you may exceed the available [Storage job](/storage/jobs/) slots, causing delays in your flow's execution. Limiting the number of concurrent component jobs to 10 is recommended. The Keboola Support team can help you adjust parallel limits. <!-- TODO(human-review): confirm the 10-parallel Storage-job guidance and default cap. -->
:::

### Execute Tasks in Parallel
Expand Down Expand Up @@ -70,6 +73,9 @@ Control the flow of execution based on conditions like:

Each of these can be evaluated for a single task, a whole phase, all or any task in a phase, or any task in the whole flow - see [What the Condition Compares](#3-what-the-condition-compares-subject).

<!-- TODO(human-review): confirm this condition-type list (status / variable values / date-time / output-table count / task duration) against the current condition builder. -->


Evaluation proceeds from top to bottom, and once a condition is true, the remaining conditions are ignored - even if others would also evaluate to be true.

:::caution
Expand Down Expand Up @@ -160,16 +166,15 @@ Task ids that no longer belong to the phase (for example a deleted or disabled t

## Variables

A flow can define its own variables — static, or computed at run time from a task result — and use
them in conditions or pass them into the components it runs. See
[Variables](/components/variables/) for both flow variables and the configuration variables they can
drive.
Variables let you store and reuse values — like dates, task results, or custom inputs — throughout your flow. Add one in a phase with the **+** icon → **Variable**; a variable holds either a **Static Value** (fixed text or number) or a **Dynamic Value** computed at run time from a task result, a phase, or a built-in function. Later conditions can then compare the variable's value, and component jobs receive flow variables that match their own variable names.

For the full guide — static and dynamic values, JMESPath aggregations, the `COUNT` and `DATE` functions, and how variables reach component jobs — see [Flow Variables](/flows/variables/). For the configuration variables that flow variables can drive, see [Variables](/components/variables/).

## Retry

You can retry failed tasks automatically and optionally choose to retry based on specific failure messages.

By default, the system retries up to 3 times with a 10-second delay between attempts. Both the number of attempts and the delay can be customized to fit your workflow.
By default, the system retries up to 3 times with a 10-second delay between attempts. Both the number of attempts and the delay can be customized to fit your workflow. <!-- TODO(human-review): confirm the retry defaults (3 attempts, 10-second delay). -->

To access the retry settings, click on task to open the configuration.

Expand Down
157 changes: 157 additions & 0 deletions src/content/docs/flows/variables/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
---
title: Flow Variables
slug: 'flows/variables'
description: Store and reuse values in Conditional Flows — static and dynamic variables, JMESPath aggregations, the COUNT and DATE functions, and how variables reach component jobs.
---

Variables in [Conditional Flows](/flows/) let you store and reuse values — like dates, task results, or custom inputs — throughout your flow. You can use them to make decisions, control flow logic, or pass dynamic values between tasks. The sections below walk through how to set up and use variables from the UI; each step also shows the JSON shape generated behind the scenes for template authors and API users.

## Adding a Variable

1. In a phase, click the **+** icon and choose **Variable**. The **Set Variable** panel opens on the right.
2. Enter a **Variable Name** — this is the identifier other tasks will use to reference the value.
3. Choose a **Variable Type** — either [Static Value](#static-value) or [Dynamic Value](#dynamic-value).

## Static Value

A **Static Value** is a fixed text or number you enter directly. Useful for thresholds, IDs, or labels that don't change between runs.

![Set Variable panel with Static Value selected](/flows/conditional-flows-variables-static-set.png)

**JSON equivalent** (useful when authoring a flow as a template or via the API):

```json
{
"type": "variable",
"name": "max_duration",
"value": 3600
}
```

## Dynamic Value

A **Dynamic Value** is computed at run time from a task result, an earlier phase, or a built-in function (see [Date & Time function](#date--time-function) below). When you pick this type, the value picker lets you browse the outputs of tasks that ran earlier in the flow. You can pick any field from the job's result tree — for example `result.output.tables`, `result.artifacts`, `result.images`, `result.configVersion`, `result.errorMessage`, and many more.

![Set Variable panel in Conditional Flow](/flows/conditional-flows-variables-set.png)

If a task produces **multiple output tables**, the picker also offers aggregations across all of them: **Sum**, **Minimum**, **Maximum**, and **Average** of a numeric field. For example, `Sum of importedRowsCount` returns the total number of rows imported by an HTTP data source across every output table.

![Dynamic Value picker showing task result tree with aggregations](/flows/conditional-flows-variables-picker.png)

:::caution
**Aggregations are not functions.** The Sum / Minimum / Maximum / Average options are not built-in functions — the `function` enum only accepts `COUNT` and `DATE`. The picker implements each aggregation as a [JMESPath](https://jmespath.org/) expression placed in the task `value` field rather than a `function` block. When authoring a flow via the API or as a template, write the aggregation directly in `value`:

- **Sum** → `sum(job.result.output.tables[].importedRowsCount)`
- **Minimum** → `min(job.result.output.tables[].importedRowsCount)`
- **Maximum** → `max(job.result.output.tables[].importedRowsCount)`
- **Average** → `avg(job.result.output.tables[].importedRowsCount)`
:::

**JSON equivalent** — behind the scenes the aggregation is stored as a `source` definition. For example, `Sum of importedRowsCount` can be expressed as a JMESPath aggregation in the task `value`. Note that the picker tree displays paths rooted at `result.*` (for example `result.output.tables`), while the generated `value` expression is rooted at `job.result.*`:

```json
{
"type": "variable",
"name": "total_imported_rows",
"source": {
"type": "task",
"task": "extract-data",
"value": "sum(job.result.output.tables[].importedRowsCount)"
}
}
```

`COUNT` and `DATE` are the only functions exposed via the `function` block (see [Date & Time function](#date--time-function) below); they take their inputs as `operands`. `COUNT` counts the items a JMESPath expression returns — for example, the number of output tables a task produced:

```json
{
"type": "variable",
"name": "table_count",
"source": {
"type": "function",
"function": "COUNT",
"operands": [
{
"type": "task",
"task": "extract-data",
"value": "job.result.output.tables"
}
]
}
}
```

The `value` field accepts [JMESPath](https://jmespath.org/) expressions, so you can filter and extract specific items from the task result instead of just walking the tree. For example, picking the name of a particular output table by its ID:

```json
{
"type": "task",
"task": "97288",
"value": "job.result.output.tables[?id=='out.c-test.example'][].name | [0]"
}
```

## Date & Time function

Returns the date/time formatted according to the specified format string, available formats:
[https://www.php.net/manual/en/datetime.format.php](https://www.php.net/manual/en/datetime.format.php).

This example returns the full textual representation of the current month, such as "July" or "August".

```json
{
"type": "function",
"function": "DATE",
"operands": [
{
"type": "const",
"value": "F"
}
]
}
```

**Example of creating a variable with the current timestamp:**

```json
{
"id": "set-timestamp",
"name": "Set Timestamp Variable",
"phase": "init",
"task": {
"type": "variable",
"name": "current_timestamp",
"source": {
"type": "function",
"function": "DATE",
"operands": [
{
"type": "const",
"value": "U"
}
]
}
}
}
```

## Using Variables in Conditions

Once a variable has been set in an earlier phase, any later **Condition** can compare its value against a constant, against another variable, or against a task result.

1. In the IF row, click the value picker and choose a variable, a task result, or a phase result from an earlier phase.
2. Choose an operator (Greater than, Equals, Contains, …).
3. Provide a comparison value — a constant, or another value picked from the tree.
4. Set the THEN and ELSE actions: **Continue To** an existing phase, or end the flow.

Only the first matching IF condition is executed; subsequent IFs in the same Conditions block are skipped.

![IF/THEN/ELSE condition referencing a task result](/flows/conditional-flows-variables-condition.png)

See also the [Conditions](/flows/#conditions) section for the full list of operators and condition types.

## How Variables Reach Component Jobs

When a phase runs a component (a job task), the variables you set earlier in the flow are merged into the component's own variables. A flow variable replaces a component variable **only if both have the same name** — flow variables whose names the component does not declare are silently ignored. This means: to let a flow drive a value inside a component, declare a variable with the matching name in the component's configuration; the flow will fill it in when the job runs.

For finer control on a specific job task, an advanced `variableOverrides` field on the task can restrict which flow variables are merged in.
1 change: 1 addition & 0 deletions src/sidebar.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export const sidebar = [
collapsed: true,
items: [
{ label: "Overview", slug: "flows" },
{ slug: "flows/variables" },
{ slug: "flows/flows-legacy" },
{ slug: "flows/flow-migration-guide" },
],
Expand Down
Loading