Skip to content

Workflow & Node Definition

A workflow is the blueprint for an execution. It's a declarative JSON structure that defines the tasks (Nodes) and the connections between them (Edges).

WorkflowDefinition

This is the main object that you provide to the WorkflowEngine. It consists of two key parts:

  • nodes: An array of Node objects.
  • edges: An array of Edge objects that connect the nodes.
typescript
const workflowDefinition: WorkflowDefinition = {
  nodes: [
    { id: "n1", type: "my-custom-node", data: { message: "Hello" } },
    { id: "n2", type: "another-node", data: { value: 123 } }
  ],
  edges: [
    { id: "e1", source: "n1", target: "n2" }
  ]
};

Here's a visual representation of a simple workflow:

Node

A Node is a single unit of work in your workflow. It has:

  • id: A unique identifier for the node within the workflow.
  • type: A string that maps to a NodeDefinition.
  • data: A JSON object containing the static configuration for this node instance. This data can be made dynamic using expressions.

Edge

An Edge defines the flow of execution between nodes. It has:

  • id: A unique identifier for the edge.
  • source: The ID of the node where the edge originates.
  • target: The ID of the node where the edge terminates.
  • sourceHandle (optional): A key for implementing conditional logic. For more details, see the Conditionals guide.

NodeDefinition

While WorkflowDefinition describes the structure, NodeDefinition describes the behavior. It's a JavaScript object that tells the engine how a certain type of node should operate.

You provide an object containing all your NodeDefinitions when you instantiate the WorkflowEngine. A schema definition library compatible with Standard Schema (like Valibot or Zod) should be used.

typescript
import { object, string, parse } from "valibot"; // Using valibot syntax

const nodeDefinitions = {
  "my-custom-node": {
    // Metadata containing validation schemas
    metadata: {
      input: object({ message: string() }),
      output: object({ status: string() }),
    },
    // The execution logic
    executor: async (data) => {
      // The 'data' type is inferred from the 'input' schema
      console.log(data.message); // "Hello"
      return { data: { status: "ok" } };
    }
  },
  // ... other node definitions
};

A NodeDefinition contains:

  • metadata: An optional object to store metadata, such as input and output schemas for validation middleware.
  • retryPolicy: An optional policy for error handling.
  • executor: An async function that contains the node's business logic. It receives the resolved data and the full context, and must return an object containing the data to be passed on.