Act on Data

The Actuate stage executes the actions that the Reason stage planned. It has two substage types: execute (does the work) and evaluate (checks whether it succeeded).

Execute Substage

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

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 type (e.g., mqtt_publish, email_send)

connection

Varies

Name of the connection to use (required for most executors)

condition

No

JavaScript expression. The executor is skipped if this evaluates to false

Template Variables in Executors

Use ${variable} syntax in executor fields (note: ${} not {{}} like in prompts):

Template Value

${action.severity}

A field from the current planned action’s params

${action.message}

A field from the current planned action’s params

${now}

Current ISO 8601 timestamp

${cycleNumber}

Current cycle number

${agentName}

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

Available Action Types

MQTT Publish

Publish a message to an MQTT topic.

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

API Call

Make an HTTP request to a configured REST API.

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

Database Write

Write data to a configured database.

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}'

Email Send

Send an email via 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 html and text fields. Providing only html will result in a SendGrid 400 error.

More Action Types

The platform handler catalog spans 9 categories. Shipped (available) handlers include:

Category Handler type(s)

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)

Industrial actions (opc_ua_write, device_command, event_bus_publish) proxy requests over HTTP to a sidecar gateway. They do not bundle native protocol libraries. Set gateway_url in the action params to point to your gateway.

Choosing the Right Risk Level

Each action type has a risk tier. Use this as a guide when deciding which autonomy lane to assign:

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

Evaluation results are stored in derivedData.evaluation and accessible in the Reflect stage to feed into 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