Skip to content

Flows

A flow is a special YAML file that represents a graphical conversation flow, as a graph consisting of nodes and links. Flows can be edited using a graphical flow editor.

Introduction

For simple bots and IVRs, having users use plain Bubblescript is often a bridge too far; the learning curve is simply too high for end users who just want to configure and "click together" a simple bot.

To overcome this, the Dialox platform offers a node-based conversation flow system, something that is quite common in other bot platforms as well. However, unlike other platforms, Bubblescript is still the backend of this flow system, giving it advantages in terms of extensibility and non-linearity.

Some design goals have been stated:

  • Each flow is managed in its own file
  • Flows have top-level properties (on which channel it executes, etc)
  • Each flow is flowchart that consists of typed nodes and links between nodes
  • Nodes and links have common properties, but also type-specific ones
  • Nodes can have variants that are more specific, e.g. 'show image', 'show audio', 'ask phone'
  • Nodes and links are aware of their capabilities and are only applicable on channels that support these capabilities
  • The types and variants of node is extensible so skills can add new node types and variants, in order to provide more specific functionality.
  • All configuration UI ("property panels") for flow/node/link properties is supported by React JSONSchema Form

The text/yaml+flow YAML schema defines a schema for a node-based dialog builder.

A flow consists of nodes and links.

Nodes have a type and a variant, both of which can be extended by skills. Each type needs to have at least a single variant. Usually, the 'main' variant is called default.

Links have types and variants as well. The types of links are fixed, however. They are currently limited to the following:

  • next - 'go to' from one node to the next
  • labelled - for presenting choices and dialog branching with quick replies / intent matching
  • trigger - for implementing handling events, intent matches and unknown messages
  • condition - for specifying conditions on branching nodes

Flow extensibility

The flow_schema YAML file can be used to add additional node types and variants to the flow editor.

# adding new node types
types: []

# adding new node variants
variants: []

# removing platform-defined defaults
omit_types: []
omit_variants: []

For each bot, the flow system looks in all folders for script files called flow_schema, and merges these files together into a single definition file.

This way, you can add new variants and types, overwrite predefined variants or types, or disable certain variant/type combinations (by using the omit_ fields).

flow_schema files are merged in script order, so the 'highest' flow definition wins.

The platform defines a set of defaults, see flow platform defaults.

CMS definitions

To expose the flow building UI in a bot, a CMS definition file needs to be created, identical to creating CMS definitions.

A content definition for a single flow:

type: flow
title: "Single flow"

storage:
  type: script
  script_title: single_flow

generators:
  - type: flow
    script_title: generated/single_flow

A content definition for a collection of flows:

title: "My flows"
type: flow
storage:
  type: script
  collection: flows/
  collection_editable: true
generators:
  - type: flow
    script_title: generated/{{ data_script_title }}

Generated Bubblescript code ends up in the generated/ folder in these examples.

Flow Variables

In the flows editor, there are several places where the UI allows users to do things with variables and expressions. These places tend to be error prone, hard to explain, and lack discoverability. These are the following places:

The node text itself, where a variable can be placed inside #{...} block:

The place where a variable needs to be picked as an answer to a question:

To overcome this at design time, flow bots have a knowledge of which "variables" can be used on these places, allowing the variables to be created on the fly and be picked / autocompleted from a list.

As you can expect, these variables can differ between each bot, depending on what kind of product / service the bot represents. Bots for making appointments could use different variables than IVR bots, for instance. This is why there are several levels of customizability in these variables. From the most system-generic to the most bot-specific, these are the following layers that can define variables:

  • Base variables - these come from the platform and represent the common exposed bubblescript variables, for instance, exposing bot.title, user.first_name, etc.

  • Skill-defined variables - each skill can add variable definitions; for instance a taxi booking bot could expose a taxi object containing information like taxi.order_price, taxi.order_date, etc.

  • Studio variables - these are the contact fields and conversation fields that can be customized by users of the platform per bot, e.g. for exposing information in the CRM.

  • Custom variables - this is a list of extra variables that a flow developer can make on the fly, for instance for temporarily storing some information in a variable for use later in the flow.

Defining variables

The base variables and skill variables are defined in the variables section of each flow_schema file. The format of the variables property is a subset of JSON schema:

variables:
  taxi:
    type: object
    properties:
      order_price:
        type: string
        title: Order price
        description: "The price of the last order in euros"
      order_date:
        type: datetime
        title: Order price
        description: "The date/time of the last order"

At compile time, all of the flow schema files are merged, resulting in one big variables schema, which can then be used inside the flows editor.

Omitting variables

When skills decide that certain variables should not be usable in the current bot they do this using the omit_variables property:

# in this bot we cannot use user.first_name
omit_variables:
  - [user, first_name]

Custom variables

Custom variables are variables that are created while the flow developer is editing a flow. They can be created from the variables side panel in the editor, or on the fly while using the flow variable picker.

Custom variables are stored in the top-level flow_schema file as follows:

custom_variables:
  - name: my_answer
    type: string
    title: Answer
    description: The answer that we must give

custom_variables_editable: true

At least one flow_schema yaml file needs to have custom_variables_editable: true, otherwise the bot does not allow creating / editing custom flow variables.

Flow JSON schema validation

  • format: "interpolated" -- The JSON schema string format called "interpolated" is used to validate flow variable string expressions, to provide validation that the referenced variables are actually available in the current bot.

  • format: "variable" -- The JSON schema string format called "variable" indicates that the string value must be an existing flow variable.

  • format: "variable_name" -- The JSON schema string format called "variable_name" indicates that the format of the string value must be a valid flow variable name, although the variable itself does not need to exist.

Flow UI widgets

In the CMS UI schema there are two new UI widgets to facilitate flow variable support:

ui:widget: interpolated

Stores a string with interpolated variables. The variables are stored in mustache format. So in the screenshot below the stored string is Hello {{ user.first_name }} {{ user.last_name }}, how are you?

Typing a slash (/) to show the variable autocompleter and to insert an existing variable.

ui:widget: variable_picker

Allows one to pick an existing variable or create a new variable (if that is allowed via the flow_schema). Unless specified otherwise, the variable will be of the type string. An alternative type can be specified via the type option of the UI schema:

form:
  # the JSON schema, describing the form
  schema:
    type: object
    properties:
      my_variable:
        type: string
        title: Order
  ui_schema:
    my_variable:
      ui:widget: variable_picker
      ui:options: { type: "@schemas.taxi_order" }

Flow Jumps

Flow jumps are visually represented in the flow editor as connection points on nodes. Each jump defined in a node's schema appears as a connectable endpoint, allowing users to create links between different parts of the flow by dragging from these points to target nodes.

In the flow editor, jumps typically appear as labeled arrows indicating both their condition and destination. For example, a "Dial: Smart" node might show multiple paths: - "Closed → Chat_multi" - directing the flow to a multi-channel chat when a call ends with "Closed" status - "Unavailable → Chat_whatsapp" - redirecting to WhatsApp when the call status is "Unavailable"

These conditional branches enable sophisticated conversation routing without requiring code. Flow jumps make complex decision trees visually intuitive, as you can see all possible paths from a node at a glance. They allow bot designers to create context-aware conversations that respond differently based on user inputs, system states, or external conditions.

Defining Flow Jumps:

Flow Jumps are automatically discovered by looking for ui:widget: 'flow_picker' in a node's UI schema, either the node's type-specific ui_schema (for general jumps related to the node type) or within a specific ui_schema for the node variant.

The system recursively searches the UI schema object to find all instances of flow_picker. For each flow_picker found, a visual flow jump is created.

  • Path: The path to the flow_picker widget within the uiSchema (e.g., ['properties', 'conditional_routing', 'cases', '0', 'target_flow']) determines how the jump is identified internally.
  • Caption: You can specify a user-friendly caption for the jump in the editor using the flow:jump_caption property alongside the ui:widget: 'flow_picker'. If not provided, the caption will default to the last segment of the path (e.g., 'target_flow' from the example above), automatically capitalized.

Example flow schema snippet for a jump point:

schema:
  type: object
  properties:
    next_step:
      type: string
      title: Next Step Target
ui_schema:
  next_step:
    ui:widget: flow_picker
    flow:jump_caption: Proceed to

Overriding and Customizing Jumps at Variant Level:

A node variant can provide a flow:jumps array directly within its uiSchema. If variant.ui_schema['flow:jumps'] is an array, this array is taken as the definitive list of jumps for that variant, and the recursive search for flow_picker widgets is bypassed. Each item in the array should be an object with path (array of strings) and caption (optional string) keys.

# In variant's ui_schema
ui_schema:
  flow:jumps:
    - path: [custom_jump_1]
      caption: Custom Jump One
    - path: [dialog_options, success_target]
      caption: On Success