Act on Data

The Actuate stage executes the actions that the Reason stage plans. The Actuate stage has two substage types: execute runs the planned actions, and evaluate checks whether the actions succeeded.

You configure the Actuate stage in stage 05 of the Agent Builder.
In the agent template YAML, you define the stage under stages.actuate.substages.

Execute Substage

The execute substage runs one or more executors for each planned action. Each executor runs one action handler. Each action handler performs a specific action. For example, publish an MQTT message, call an API, write to a database, or send an email.

In the Agent Builder, you use the Action type field to select an action handler for the executor.
In YAML, the type field under executors defines the action handler.
The evaluate substage verifies action success, for example, by checking for an HTTP 200 response from SendGrid or a broker acknowledgment for MQTT.

actuate:
  substages:
    - type: execute
      name: alert-publisher
      executors:
        - type: mqtt_publish
          connection: factory-mqtt
          topic: factory/alerts/temperature
          payload:
            severity: '${action.severity}'
            message: '${action.message}'
            timestamp: '${now}'
            source: quality-monitor

        - type: email_send
          connection: alert-email
          condition: "${action.severity == 'critical'}" # Only send for critical alerts
          subject: 'CRITICAL ALERT: ${action.sensorType} threshold exceeded'
          html: |
            <h2>Critical Alert</h2>
            <p><strong>Message:</strong> ${action.message}</p>
            <p><strong>Time:</strong> ${now}</p>
          text: |
            CRITICAL ALERT
            Message: ${action.message}
            Time: ${now}

Executor Fields

Field Required Description

type

Yes

The action handler. For example, mqtt_publish, email_send. The Action type field in the Agent Builder sets this value.

connection

Varies

Name of the connection to use. Most executor types require a connection.

condition

No

JavaScript expression that returns true or false. If the expression evaluates to false, the platform skips the executor.

Template Variables in Executors

Use ${variable} syntax in executor fields:

Template Value

${action.severity}

A field from the params of the current planned action.

${action.message}

A field from the params of the current planned action.

${now}

Current ISO 8601 timestamp.

${cycleNumber}

Current cycle number.

${agentName}

Agent name from the data-defined agent (DDA) configuration.

Executor variable fields use ${variable} syntax. LLM prompts use {{}} syntax.

Action Handlers

You can add an action handler to an executor in two ways:

  • In the Agent Builder, open the Actuate stage and select the Action type field of a plan card with the Execute badge to open a list of action handlers. The handler picker groups action handlers into nine categories: Communication, Human Workflow, Messaging & Events, System & Application, Data & State, Industrial / OT, Collaboration, Governance & Safety, and Integration. The picker shows the action name, risk tier, and required connection types of each handler.

  • In the agent template YAML, you add an entry to the executors list of the execute substage. The type field selects the action handler, and the remaining fields configure the handler.

Some action handler categories are placeholders and do not yet contain any shipped handlers.

The following section shows YAML configuration examples for frequently used handlers:

Publish to MQTT Topic

Publish a message to an MQTT topic on a configured broker:

executors:
  - type: mqtt_publish
    connection: factory-mqtt
    topic: factory/alerts/${action.sensorType}
    payload:
      type: '${action.severity}'
      message: '${action.message}'
      timestamp: '${now}'
      source: threshold-monitor

Call REST/GraphQL API

Make an HTTP request to a configured REST or GraphQL API endpoint:

executors:
  - type: api_call
    connection: erp-api
    method: POST
    path: /api/v1/maintenance-requests
    body:
      equipmentId: '${action.params.equipmentId}'
      priority: '${action.params.priority}'
      description: '${action.params.description}'
      requestedBy: quality-monitor

Write to Database

Execute a write query against a configured database connection:

executors:
  - type: database_write
    connection: quality-db
    query: |
      INSERT INTO quality_events (timestamp, metric_name, value, severity, message)
      VALUES ($1, $2, $3, $4, $5)
    params:
      - '${now}'
      - '${action.params.metricName}'
      - '${action.params.value}'
      - '${action.params.severity}'
      - '${action.params.message}'

Send Email

Send an email through SendGrid or SMTP:

executors:
  - type: email_send
    connection: alert-email
    condition: "${action.severity == 'critical'}"
    subject: 'CRITICAL ALERT: ${action.params.sensorType} threshold exceeded'
    html: |
      <h2>Critical Threshold Alert</h2>
      <p><strong>Sensor:</strong> ${action.params.sensorType}</p>
      <p><strong>Message:</strong> ${action.params.message}</p>
      <p><strong>Time:</strong> ${now}</p>
    text: |
      CRITICAL THRESHOLD ALERT
      Sensor: ${action.params.sensorType}
      Message: ${action.params.message}
      Time: ${now}
    priority: high

The email_send executor requires both the html and text fields. If you provide only the html field, SendGrid returns a 400 error.

Action Handlers per Category

Category Handler Types

Communication

email_send, slack_message.

Human Workflow

hitl_request.

Messaging & Events

mqtt_publish, agent_message.

System & Application

api_call.

Data & State

database_write.

Integration

mcp_tool_call.

Industrial / OT

opc_ua_write, device_command, event_bus_publish (gateway HTTP-proxy pattern).

Governance & Safety

Pending

Collaboration

Pending

The industrial executors (opc_ua_write, device_command, event_bus_publish) do not communicate with industrial protocols directly. Each executor sends the request over HTTP to a gateway service that you run alongside the orchestrator. The gateway translates the request into the industrial protocol. Set gateway_url in the action params to point to the address of your gateway.

Choose the Right Risk Level

The platform assigns a risk tier to each action handler. The tier appears as a badge in the action handler picker. Use the tier as a guide when you assign an autonomy lane. For more information, see Set Human Oversight:

Risk Tier Examples Suggested Lane

low

Log observations, publish status updates

Autonomous

medium

Send alerts, update configurations

Supervised

high

Write to production databases, create tickets

Controlled

critical

Stop production lines, delete records

Controlled (always)

Evaluate Substage

The evaluate substage checks whether the executed actions succeeded:

actuate:
  substages:
    - type: execute
      name: alert-publisher
      executors:
        - type: mqtt_publish
          # ...

    - type: evaluate
      name: result-checker
      successCriteria:
        minSuccessRate: 0.8 # At least 80% of actions must succeed
      verifications:
        - type: mqtt-ack
          timeoutMs: 5000 # Wait up to 5 seconds for MQTT acknowledgement

Actuate Stage Inputs and Outputs

The plan substage of the Reason stage selects actions each cycle and writes them to derivedData.plan. For more information, see Reason Stage Inputs and Outputs.

Evaluation results are stored in derivedData.evaluation and accessible in the Reflect stage to inform learning.

Field Description

minSuccessRate

Fraction of actions that must succeed (0.0–1.0).

mqtt-ack verification

Wait for MQTT PUBACK (QoS 1) within timeoutMs.

Next Steps