Flow YAML Authoring

Most users can build Flows entirely through the OOMOL Studio UI. This page is for cases where you want to understand or edit the underlying YAML model directly.

For authoring rules about secrets, OOMOL auth, Fusion-first decisions, and sessionDir fallback patterns, see Secrets, Auth, and Runtime Paths.

Where Reusable Units Live

The most common authoring units are stored in these directories:

UnitDirectoryMain file
Flowflows/{name}/flow.oo.yaml
Task Blocktasks/{name}/task.oo.yaml
Subflow Blocksubflows/{name}/subflow.oo.yaml
Slotflowslotflows/+slotflow#N/slotflow.oo.yaml

In practice:

  • A Flow is the runnable entry point.
  • A task Block is a reusable single operation.
  • A subflow Block is a reusable multi-step workflow.
  • A slotflow is a small workflow used to implement a slot contract.

Reference Forms

The most common local reference forms are:

What you want to referenceYAML form
Local tasktask: self::{name}
Local subflowsubflow: self::{name}
Local slotflowslotflow: self::+slotflow#N

When the target comes from another package, replace self:: with that package namespace.

Public Contract vs Internal Wiring

OOMOL YAML separates two concerns:

ConcernTypical fieldsMeaning
Public contractinputs_def, outputs_defWhat the reusable unit publicly accepts and returns
Internal wiringinputs_from, outputs_from, from_flow, from_nodeHow data actually moves between boundaries and internal Nodes

Core Fields

long_running

Used mainly in task.oo.yaml to indicate that a task is expected to run much longer than ordinary tasks.

long_running: true

Recommended rule of thumb:

  • Default is to omit the field, or keep it false.
  • Use true only for clearly long-running work, usually 10+ minute or strongly input-scaled processing.
  • Do not use it for one-shot API calls, short conversions, or ordinary quick tasks.

inputs_def

Defines the input Handles that a task, subflow, or slot accepts.

inputs_def:
- handle: array
json_schema:
type: array

outputs_def

Defines the output Handles that the reusable unit promises to return.

outputs_def:
- handle: result
json_schema:
type: string

inputs_from

Defines where an individual Node gets each input from.

inputs_from:
- handle: text
from_node:
- node_id: reader#1
output_handle: text

The source can be one of these:

  • from_node: read from another Node inside the current Flow or subflow
  • from_flow: read from the public boundary of the current subflow or slotflow
  • value: use an inline value

outputs_from

Defines how a subflow or slotflow exposes internal results to the outside.

outputs_from:
- handle: result
from_node:
- node_id: formatter#1
output_handle: text

Without root-level outputs_from, a subflow may complete internally but still expose no usable public output.

forward_previews

Used in subflow.oo.yaml to forward selected internal previews to the caller Flow.

forward_previews:
- files-downloader#1

This lets a subflow stay internally complex while still surfacing the most useful previews externally.

Recommended rule of thumb:

  • Forward only the 1-2 previews that matter most to the caller.
  • Prefer artifact previews or progress-relevant previews.
  • Do not forward every internal preview by default.

Common Wiring Patterns

Task Node in a Flow

nodes:
- node_id: summarize#1
task: self::summarize
inputs_from:
- handle: text
from_node:
- node_id: reader#1
output_handle: text

Subflow Node in a Flow

nodes:
- node_id: filter#1
subflow: self::filter
inputs_from:
- handle: array
from_node:
- node_id: +value#1
output_handle: array

Slotflow Bound to a Subflow Slot

nodes:
- node_id: filter#1
subflow: self::filter
slots:
- slot_node_id: +slot#1
slotflow: self::+slotflow#1

Slot Contracts

A slot defines a behavior boundary inside a subflow:

- node_id: +slot#1
node_type: slot_node
slot:
inputs_def:
- handle: item
json_schema: {}
outputs_def:
- handle: predicate
json_schema:
type: boolean

Important rules:

  • The slot still needs inputs_from wiring to receive upstream data.
  • The slotflow must return outputs using the exact same public Handle names expected by the slot.
  • Extra slot parameters usually need both declaration and wiring in the caller Flow.

Nullable and Defaults

Optional Handles can be described with nullable.

inputs_def:
- handle: output_dir
json_schema:
type: string
nullable: true

When the intended default is genuinely empty, an empty value: is often better than inventing a placeholder value that later needs special handling.

Multi-Source Outputs

Some subflows can finish through more than one valid branch. In that case, one public output can route from multiple internal sources:

outputs_from:
- handle: array
from_node:
- node_id: reducer#1
output_handle: array
- node_id: switch-by-length#1
output_handle: "0"

This pattern is commonly used for short-circuit branches such as empty-array handling.

Array-Oriented Subflow Pattern

Reusable array-processing subflows often follow this shape:

This pattern helps keep empty-array handling, per-item behavior, and final aggregation separate.

Validation Checklist

Before assuming the runtime is wrong, check these authoring rules first:

  1. Handle names must match exactly.
  2. Required inputs must be wired, unless they are intentionally nullable.
  3. Local reusable-unit references should use the correct namespace form such as self::.
  4. Subflows should expose public results through root-level outputs_from.
  5. Slot outputs and slotflow outputs should use the same Handle names.
  6. Ordinary Flows should not contain direct circular dependencies.

For the UI-side explanation of subflows and slots, see Subflow Block Advanced Usage.