Skip to main content
In the Inworld Agent Runtime, edges connect nodes in the graph and define how data flows between them. Edges determine the execution flow of the graph and can apply conditions or other controls to the data passing between nodes.

Basic Edge

The simplest form of edge is one that connects nodeA to nodeB, where the output of nodeA is passed as input to nodeB without any conditions.
// Create a basic edge from nodeA to nodeB
graph.addEdge(nodeA, nodeB);

Conditional Edge

You can create an edge with a condition that determines whether data flows through the edge. There are two ways you can define conditions:
  1. Common Expression Language expressions: Define the logic using CEL expressions.
  2. Custom condition: Define a function that returns either true or false.

Common Expression Language (CEL)

Common Expression Language (CEL) implements common semantics for expression evaluation that can be used to define edge conditions. CEL expressions operate on the output of the source node, which is accessible via the input variable. Some examples of supported operators include:
  • input.content == 'foo' - Returns true if input content is equal to the constant string literal argument.
  • input.intent_name == "greeting" - Returns true if the intent name equals “greeting”.
  • size(input) > 0 - Returns true if the size of input is greater than 0.
  • int(input.content) > 50 - Returns true if the numeric value of input content is greater than 50.
See the CEL Language Definition for more details. In the example below, data only flows from nodeA to nodeB if the numeric value of the content is greater than 50.
// Example: data flows if numeric content is greater than 50
graph.addEdge(nodeA, nodeB, {
  conditionExpression: 'int(input.content) > 50'
});

Basic Syntax

CEL expressions are used in the conditionExpression parameter when adding edges to your graph:
.addEdge(sourceNode, targetNode, {
  conditionExpression: 'input.confidence > 0.8'
})

Understanding the Input Object

In CEL expressions, input refers to the data output from the source node that the edge is connected to. When an edge is evaluated, CEL receives the previous node’s output as the input object.
Example flow
// UserAuthNode outputs: { user: { id: "123", tier: "premium" }, isAuthenticated: true }
// The edge condition receives this as 'input'
.addEdge(userAuthNode, premiumFeatureNode, {
  conditionExpression: 'input.user.tier == "premium" && input.isAuthenticated == true'
})
Key Points
  • input = output data from the source node of the edge
  • Structure varies based on what the source node produces
  • Always verify the source node’s output format before writing CEL expressions

The Data Store Object

In addition to input, CEL expressions also have access to a data_store object that provides persistent storage across graph execution. The data store allows you to share state between different nodes and maintain context throughout the graph’s lifecycle.
Data Store Operations
Checking if a Variable Exists
data_store.contains('variable_name')
Getting a Variable Value
data_store.get('variable_name')
Note: Data store values are stored as objects with a text property, so you need to access .text to get the actual value:
data_store.get('my_bool_var').text == 'true'
Data Store vs Input
Aspectinputdata_store
ScopeCurrent edge onlyEntire graph execution
SourcePrevious node’s outputPersistent storage across nodes
LifecyclePer edge evaluationGraph lifetime
Use CaseNode-to-node data flowCross-node state management
Data Type Limitations
Important: The Inworld Agent Runtime only supports simple data types in node inputs and outputs. Complex JavaScript objects and class instances are not supported.
Supported Types:
  • Primitives: string, number, boolean
  • Arrays of primitives: string[], number[], boolean[]
  • Plain objects with primitive properties: { name: string, age: number }
  • Nested plain objects: { user: { id: string, tier: string } }

Conditional expressions in code

For more advanced conditions that cannot be expressed by CEL expressions, a condition function can be defined directly in the edge configuration. In the example below, data only flows from nodeA to nodeB if the custom condition function returns true.
// Custom condition function
graph.addEdge(nodeA, nodeB, {
  condition: (context, input) => {
    return Number(input.content) > 50;
  }
});

Optional Edge

Marks an edge as optional, meaning the destination node can execute even if it doesn’t receive input through this edge. Optional edges are useful when a node can function with or without certain inputs.
// Mark the edge from nodeA to nodeB as optional
graph.addEdge(nodeA, nodeB, {
  optional: true
});

Loop Edge

Creates a loop in the graph, allowing for iterative processing. The below example creates a self-loop where the output of nodeA is fed back as its input, enabling iterative processing until a condition is met.
// Create a loop edge from nodeA back to itself
graph.addEdge(nodeA, nodeA, {
  loop: true
});
Loops are often used with a condition to control when the loop terminates:
// Create a loop edge with a condition to control termination
graph.addEdge(nodeA, nodeA, {
  loop: true,
  conditionExpression: 'input.shouldContinue == true'
});