Skip to content

Flowlets & Islets

Flowlets & Islets

Flowlet Structure

A flowlet is the full configuration of one step in a flow:

{
"name": "Send Notification",
"ref": "sendNotification",
"appId": "send-mail",
"index": 2,
"args": {
"to": "{{ $prev.getUser.email }}",
"subject": "Your report is ready",
"body": "<p>Report attached.</p>",
"attachments": ["{{ $prev.generateReport.filePath }}"]
},
"timeout": 15,
"retry": {
"count": 2,
"delayMs": 500,
"backoffMultiplier": 2,
"jitter": true
},
"filters": [...],
"needsApproval": false,
"componentConfigIds": {
"request": "65smtp-component-id"
}
}

Filters

Filters are pre-execution conditions. The flowlet only runs if all filters evaluate to true.

"filters": [
{
"leftValue": "{{ $prev.checkBalance.amount }}",
"operator": "gte",
"rightValue": "1000",
"cast": "number",
"mode": "and"
},
{
"leftValue": "{{ $prev.getUser.tier }}",
"operator": "eq",
"rightValue": "premium",
"mode": "and"
}
]

Filter fields:

  • leftValue — expression or static value (left side of comparison)
  • operatoreq, neq, gt, gte, lt, lte, contains, not_contains, is_empty, not_empty, regex
  • rightValue — value to compare against
  • cast — type cast before comparison: string, number, boolean
  • modeand (all must pass) or or (any must pass)

Retry Configuration

"retry": {
"count": 3,
"delayMs": 1000,
"backoffMultiplier": 2.0,
"jitter": true
}
  • count: max retry attempts after the first failure
  • delayMs: initial delay before first retry
  • backoffMultiplier: multiply delay by this factor on each retry (exponential backoff)
  • jitter: add random variation to delay to prevent thundering herd

With count: 3, delayMs: 1000, backoffMultiplier: 2:

  • Attempt 1: immediate
  • Retry 1: after ~1s
  • Retry 2: after ~2s
  • Retry 3: after ~4s

Timeout

"timeout": 30

Timeout in seconds. If the module does not complete within this time, the flowlet fails with a timeout error. The retry logic then applies.

Approval Gates

When needsApproval: true, the play pauses at that step and enters WAIT state. An approval request is sent to the designated user:

{
"ref": "approvePayment",
"appId": "var",
"needsApproval": true,
"args": {"approvalNote": "Please review the ${{ $prev.calcTotal.amount }} payment"}
}

The play only continues after the user approves via the UI or API. If declined, the play moves to FAIL.

Component Override Per Flowlet

Override the default component for a specific step:

"componentConfigIds": {
"ai": "65anthropic-component-id",
"storage": "65s3-prod-component-id"
}

This lets you use a specific AI provider or storage backend for just this step, without affecting other steps in the flow.

Islets

Islets are isolated sub-executions within a play. They run in their own execution context, separate from the main play’s state. Used for:

  • Running a set of steps against each item in a collection (powered by the Iterator module)
  • Fire-and-forget side effects that shouldn’t block the main flow
  • Parallel processing branches that merge back via Aggregator