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.