Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/pixlcore/xyops/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Workflows in xyOps are visual graphs of nodes connected by wires that control job execution. Conceptually, a workflow is an event with an embedded graph and special runtime behavior. When a workflow runs, it becomes a “workflow job” which may spawn any number of sub-jobs on connected nodes. The system manages their lifecycle, collects results, applies actions and limits, and tracks everything in the parent job record.
Workflows run everything in parallel by default, with concurrency governed by resource limits you attach to individual nodes.

How Workflows Execute

At a glance:
  1. A trigger node fires (e.g. manual trigger, schedule trigger). This starts the workflow job and “lights” the trigger node.
  2. All nodes wired from that trigger activate. Multiple outputs run in parallel unless constrained by limits.
  3. Event or job nodes launch sub-jobs. Their completion result determines which outgoing wires fire next.
  4. Controller nodes implement fan-out/fan-in, loops, conditionals, delays and multiplexing.
  5. Action and limit nodes visually attach to event/job nodes and are merged into the launched sub-jobs.
  6. The workflow completes when no nodes are active and all sub-jobs are finished or aborted.

When to Use Workflows

Orchestration

Coordinate multiple jobs with conditional logic, joins, and delays

Fan-Out Processing

Split a dataset or file list and process items concurrently, then join results

Multi-Target Runs

Run the same job on many servers with optional staggering

Reusability

Compose pre-defined events into larger flows, or create ad-hoc job nodes

Graph Editor

The workflow editor provides:
  • Connect Nodes: Click pole buttons to solder connections. Invalid pairs are suppressed by the UI.
  • Add Node: Click “Add Node” or solder from a pole and click the background to insert a new node in place.
  • Duplicate: Select one or more nodes (shift-click) and duplicate; connections between selected nodes are preserved.
  • Detach: Detach all connections to/from selected nodes.
  • Delete: Delete selected nodes and any connected wires. Deleting a trigger node also removes the underlying trigger.
  • Undo/Redo: Up to 100 levels for all editor operations.
  • Zoom/Scroll: Zoom in/out/reset and drag to pan.
  • Test Selection: Run a test starting from the selected node or only that single node.

Node Types

Nodes have connection “poles” on their sides:
  • Input pole (left): Incoming flow
  • Output pole (right): Outgoing flow
  • Limit pole (bottom): For event/job nodes to attach limit nodes

Trigger Nodes

Trigger nodes visually represent event triggers inside the graph, such as manual, schedule, interval, webhook or plugin triggers. They have a single output and typically feed Event, Job, or Controller nodes.
Special trigger option bubbles (Catch-Up, Range, Blackout, Delay, Precision) have no poles and are purely modifiers that light up when their associated scheduled trigger fires.

Event Nodes

Event nodes place a pre-created event on the graph. You can override targets, algo, tags and user parameters for that use. When the node runs, the sub-job inherits the event’s configuration plus the node’s overrides.
{
  "id": "nbiq3bju",
  "type": "event",
  "data": {
    "event": "emcr7qj6x6p",
    "params": {},
    "targets": [],
    "algo": "",
    "tags": []
  },
  "x": 130,
  "y": 481.4453125
}
If the referenced event is a workflow, it must include an enabled manual trigger so the engine knows where to start the sub-workflow.

Job Nodes

Job nodes are ad-hoc jobs without a backing event. You choose a plugin and provide any parameters, plus optional title/icon/category, targets, algo and tags. Actions and limits attached in the graph are merged into the launched sub-job at runtime.
{
  "id": "n3duezg7",
  "type": "job",
  "data": {
    "params": {
      "script": "#!/bin/sh\n\necho \"Processing complete.\"\n",
      "annotate": true,
      "json": false
    },
    "targets": ["main"],
    "algo": "random",
    "tags": [],
    "label": "Process Data",
    "category": "general",
    "plugin": "shellplug",
    "icon": ""
  },
  "x": 505,
  "y": 165
}

Action Nodes

Action nodes attach post-job actions to event/job nodes and are merged into the launched sub-job with the selected condition. Typical uses include email notifications, webhooks, or disabling/deleting future runs. Action nodes have a single input and connect from event/job nodes.

Limit Nodes

Limit nodes attach resource controls to event/job nodes and are merged into the launched sub-job’s limits. Examples include Max Concurrent Jobs, Max Queue Size, CPU/Memory/Time limits. A limit node connects via the bottom limit pole on an event/job node.

Controller Nodes

Controllers implement flow control. They have input and output poles and connect in-line between other nodes.

Split Controller

The Split controller fans out work by taking an input list and launching one sub-job per item. Provide a dot-path to the list in the previous job context, such as data.rows.
  • The engine resolves the path and expects an array
  • If the value is a string it is trimmed and split by newline
  • A special case is files, which splits the incoming files array so each sub-job receives exactly one file
  • Each individual sub-job receives one item in Job.input, either in data as item or as a File in the files array
  • Split requires exactly one output connection to the Event or Job node it will run per item
  • Concurrency and queuing are governed by limits attached to that node
  • After all items complete, use a continue wire from the controlled node
  • Includes a “continue percentage” setting to require N% of sub-jobs succeed before continuing

Join Controller

The Join controller waits for multiple incoming flows to finish, then passes a combined result to the next step. You can wire multiple inputs into a Join; it initializes when the first input arrives and completes after all inputs have fired.
{
  "items": [
    { "foo": 1234 },
    { "foo": 1234 },
    { "foo": 1234 }
  ],
  "combined": {
    "foo": 1234
  }
}
All input job data is appended to an items array, and also separately all job data is shallow-merged into a combined object. Any files produced upstream are concatenated and passed along.

Repeat Controller

The Repeat controller runs the same Event or Job node a fixed number of times. All runs are launched immediately and will queue or run in parallel based on the limits attached to the target node.
To control series/parallel execution, attach “Max Concurrent Jobs” and “Max Queue Size” limit nodes to the event/job node.

Multiplex Controller

The Multiplex controller runs a job across many servers. It expands the target selection from the destination Event/Job into concrete server IDs, filters to currently enabled servers, and applies server alert filters. It then launches one sub-job per server. An optional stagger setting delays starts by a fixed interval per job, which helps avoid thundering herds.

Decision Controller

The Decision controller evaluates a JEXL expression (with xyOps extensions) against the previous job context. If the expression evaluates to true, the controller passes control to all connected outputs; when false, no outputs fire.
data.random > 0.5
The UI provides an “Expression Builder” button to explore output data from recently completed jobs and pick out a specific JSON key path.

Wait Controller

The Wait controller pauses flow for a configured duration, then passes control to all connected outputs. It maintains active state while waiting and is aborted if the workflow is aborted.

Connections and Conditions

Connection rules by node type:
  • Triggers → Event, Job, or Controller nodes
  • Event/Job ← Trigger/Event/Job/Controller nodes → Event/Job/Action/Controller nodes
  • Action ← Event/Job nodes only
  • Limit → Bottom pole of Event/Job nodes
  • Controllers ← Trigger/Event/Job nodes → Event/Job nodes

Wire Conditions

Conditions on wires from Event/Job nodes determine which outputs fire when a sub-job completes:
ConditionFires When
completeAlways fires
successExit code 0
errorAny failure
warningCode is “warning”
criticalCode is “critical”
abortJob was aborted
tag:NAMEJob produced tag NAME
continueAfter Repeat/Multiplex/Split completes (when success threshold met)

Continue After Controllers

Repeat, Multiplex and Split support a “continue after controller” flow:
1

Configure Percentage

Set the controller’s “continue percentage” (0-100). This is the minimum percentage of successful sub-jobs required to proceed.
2

Wire Continue Condition

Solder wires out of the controlled Event/Job node with the continue condition to define what happens next.
3

Execution

When all iterations complete, if successes meet or exceed the threshold, all continue wires from that Event/Job fire.
Example: Event A → Repeat (x10) → Event A has a continue wire → Event B. After all 10 runs of Event A finish, if at least N% succeed, Event B runs.

Data Passing Between Nodes

Inputs and outputs are automatically passed along:
  • At workflow start, inbound input.data and input.files are passed to the trigger node
  • When an Event/Job finishes, its output data and files are passed to downstream nodes as input.data and input.files
  • If the workflow has user fields defined, these are passed to all sub-jobs via workflow.params
  • User tags from sub-jobs bubble up to the workflow job and can drive tag:... conditions
  • HTML and table content: if a sub-job emits html or table, it bubbles up to the parent
  • Retries: if a sub-job was retried, its data/files are not bubbled

Join Specifics

The next node after a Join Controller receives custom input.data with:
  • items: Array of each upstream job’s data
  • combined: Shallow merge of all data
  • Files are concatenated onto the input.files array

Split Specifics

  • The Split controller resolves its data path against the previous job context
  • If the path is files, each incoming file is sent to a separate sub-job
  • Otherwise, each array element becomes input.data = { item: ... }

Event vs Job Nodes

When to use each:
Event NodeJob Node
References pre-created eventAd-hoc job without event
Reusable configurationQuick one-offs
Plugin params, targets, algo, actions, limitsPick plugin and fill params in editor
Can override targets, algo, tags, paramsFaster for inline scripts

Tips and Best Practices

Everything runs in parallel by default. Attach Max Concurrent Jobs and Max Queue Limit limits to throttle fan-out.
For Repeat/Multiplex/Split, use continue wires from the controlled node to handle “after all done” steps, optionally with a success threshold.
Use Join to aggregate multiple upstream results; the next node sees both items and a combined object.
Prefer success/error wires for the main paths and add warning, critical, abort, or tag:NAME for special handling.
For massive multi-server jobs, add a Multiplex controller with a stagger to avoid spikes.
Split on files to process one file per sub-job; combine results with Join.

Events

Learn about the event system

Triggers

Configure workflow triggers

Actions

Attach actions to workflow nodes

Limits

Set resource constraints

Build docs developers (and LLMs) love