Dibbla Docs Get started Guides Workflows Changelog
Open Console
Beyond apps

Workflow YAML reference

The slim format dibbla wf create -f consumes — three node types, the edge syntax, and the handful of rules that decide whether a graph runs.

The format dibbla wf create -f and wf update -f read. Write this, not the verbose React-Flow JSON the editor stores — the CLI converts between them.

Build your first workflow is the walkthrough; this is the field reference.

The whole shape

name: incident_triage          # required, unique in the org

nodes:
  - id: api_input              # entry point
    type: api
    inputs: [question]         # what a caller must send
    outputs: [question]        # what downstream nodes can read

  - id: reasoning_agent_function
    type: function
    function: reasoning_agent_function   # from the registry
    server: function-server              # which execution server provides it
    inputs:                              # literals, or left for an edge to fill
      system_message: "You are an incident triage assistant. Be brief."
      model: dibbla/claude-haiku-4-5
    outputs: [response]

  - id: api_response
    type: api_response
    linked_to: api_input       # ties the reply to its entry node
    inputs: [response]

edges:
  - api_input.question -> reasoning_agent_function.prompt_message
  - reasoning_agent_function.response -> api_response.response

Node types

typePurposeFields you needEnforced by wf validate
apientry point; defines what callers sendid, inputs, outputsnothing beyond typeoutputs defaults to inputs
functionone call to a registry functionid, function, serverfunction, server
api_responsewhat the caller receivesid, linked_to, inputslinked_to

The two columns differ on purpose. The validator is lenient — an api node with no ports passes — but a graph built that way cannot do anything. Write the middle column; do not read a clean validate as confirmation you did.

An api node is required for every execution, including from the CLI. dibbla wf execute posts to the same endpoint the HTTP caller does, and it returns No API node found without one. The api_response node is what makes a caller receive something: omit it and a blocking execute waits out the 30-minute timeout and returns 408.

Edges

One per line, from.output -> to.input. The left side must be an output the producing node declares; the right side an input the consuming node accepts.

edges:
  - api_input.question -> summarise_incidents.region
  - summarise_incidents.summary -> api_response.response

The rules that actually bite

Only wire ports the registry declares

Adding a plausible output a function does not have — an error port, say — produces preflight: malformed source handle, and the run then hangs rather than failing. A hang and a typo look nothing alike, which is what makes this one expensive. dibbla fn get <server> <function> is the ground truth for what exists.

Your node ids do not survive a round-trip

Custom ids work: edges and tools: resolve against them when you create the workflow. What they do not do is come back. The platform stores its own internal ids, and wf get regenerates a slim id from each node’s label — which for a function node defaults to the function name. So the file you wrote and the file you read back differ, and a diff between them is noise rather than drift.

One node, one role — and validate will not catch this one

A node may be an agent’s tool or a data input to that agent — never both. Wiring both closes a cycle (the implicit tool edge plus your data edge) and the run is rejected with CYCLE_DETECTED before it starts. To put data in an agent’s context, template it into the system message and keep that node out of tools:.

The validator builds its cycle check from edges: alone and never adds the implicit edges from tools:, so a tool-induced cycle passes both validate and create cleanly and only fails when you trigger it. It is the one class of error the section below cannot protect you from.

Types must match the function’s reflected types. Send true, not "true"; 42, not "42". dibbla fn get prints them.

Validate before you create

$dibbla wf validate -f incident_triage.yaml
valid: true
node_count: 3   edge_count: 2
 
$dibbla wf create -f incident_triage.yaml
 
# snapshot HEAD before editing an existing one
$dibbla revisions create incident_triage
$dibbla wf update incident_triage -f incident_triage.yaml

validate changes nothing on the platform, so it is cheap to run on every edit — but it is a server call, not a local parse. It needs your token, and it resolves the live function registry, so a function whose execution server is currently offline validates differently from one that is connected.

Round-trip an existing workflow to learn the shape

dibbla wf get <name> -o yaml prints any workflow in this format — usually faster than reading a schema. Note it returns the converted form, so a node you named yourself comes back named after its function — see the round-trip warning above.

Updating safely

wf update sends the current ETag, so a concurrent edit returns 412 rather than silently overwriting someone. Pull, merge, retry — --force exists but discards whatever the other writer just shipped.

And remember the editor has no save button: every change made there writes the live HEAD immediately. Take a revision first.