Version: Latest

Actions

When a Rasa assistant calls a custom action, it sends a request to the action server. Rasa only knows about whatever events and responses come back in the request response; it's up to the action server to call the correct code based on the action name that Rasa provides.

To better understand what happens when Rasa calls a custom action, consider the following example:

You have deployed a weather bot to both Facebook and Slack. The user can ask for the weather with the intent ask_weather. There is a slot location which will be filled if the user has specified a location. The action action_tell_weather will use an API to get the weather forecast , using a default location if the user doesn't specify one. The action will set the temperature to the maximum temperature of the weather forecast. The message returned will differ according to the channel they are using.

Protocols supported by the action server

Action server supports two protocols for communication with Rasa server:

HTTP(S) Protocol

API specification for HTTP protocol can be found here.

Compressed body in HTTP requests

Rasa has the capability to compress the HTTP request body for custom actions. By default, this option is off to keep backward compatibility with older versions of custom action servers which did not receive the compressed body in the HTTP request for custom actions. To enable this option, set environment variable COMPRESS_ACTION_SERVER_REQUEST to True.

Rasa SDK versions 3.2.2, 3.3.1, 3.4.1 and upwards, support both compressed and non-compressed body in the HTTP request for running custom action server. There is no additional setup required.

HTTP Protocol

To connect to the action server using the HTTP protocol, you need to set protocol schema to http in the url of the action_endpoint in your endpoints.yml file:

action_endpoint:
url: "http://localhost:5055/webhook"

When using the HTTP protocol, make sure that the action server is started with HTTP enabled.

HTTPS Protocol

To use the HTTPS protocol to connect to action server, set the protocol schema to https in the url of the action_endpoint and provide CA certificate in cafile field in your endpoints.yml file:

action_endpoint:
url: "https://localhost:5055/webhook"
cafile: "/path/to/ssl_ca_certificate"

When using the HTTPS protocol, make sure that:

GRPC Protocol

New in 3.9

API specification for gRPC protocol can be found here. Data schema for gRPC protocol is closely aligned with the HTTP protocol.

We use compression by default in gRPC protocol. It cannot be disabled.

We support both secure (TLS) and insecure gRPC connections.

Insecure gRPC connection

To connect to the action server over insecure gRPC connection, you need to set the protocol schema to grpc in the url field of the action_endpoint in your endpoints.yml file:

action_endpoint:
url: "grpc://localhost:5055"

When using an insecure gRPC connection, make sure that the action server is started with insecure connection enabled.

Secure (TLS) gRPC connection

To connect to the action server over a secure gRPC connection, you need to provide the path to the SSL CA certificate, in the cafile field in your endpoints.yml file:

action_endpoint:
url: "grpc://localhost:5055"
cafile: "/path/to/ssl_ca_certificate"

When using a secure gRPC connection, make sure that:

Custom Action Input

Note: HTTP protocol is used in the example below. The input format for gRPC protocol follows a similar data layout. For example, the json payload below can be serialized to the gRPC request object and send it to the action server over gRPC protocol.

Your action server receives the following payload from the Rasa server:

Some fields in the payload are optional and may not be present in all requests. Fields marked as object have a very complex structure and are not shown here.

# pseudo code
request {
next_action: { type: string }
sender_id: { type: string }
tracker: { type: object }
domain: { type: optional[object] }
domain_digest: { type: optonal[string] }
version: { type: string }
}
domain {
config: { type: object }
session_config: { type: object }
intents: { type: object }
entities: { type: object }
slots: { type: object }
responses: { type: object }
actions: { type: object }
forms: { type: object }
e2e_actions: { type: object }
}
tracker {
sender_id: { type: string }
slots: { type: object }
latest_message: { type: object }
events: { type: array_of_objects }
paused: { type: bool }
followup_action: { type: optional[string] }
active_loop: { type: map }
latest_action_name: { type: string }
stack: { type: array_of_objects }
}

Fields in the payload

Following is the description of the fields in the payload.

next_action

The next_action field tells your action server what action to run. Your actions don't have to be implemented as classes, but they do have to be callable by name.

In the example case, your action server should run the action action_tell_weather.

sender_id

The sender_id tells you the unique ID of the user having the conversation. Its format varies according to the input channel. What it tells you about the user also depends on the input channel and how the user is identified by the channel.

In the example case, the sender_id is not used for anything.

tracker

The tracker contains information about the conversation, including a history of events and a record of all slots:

  • sender_id: The same sender_id as is available in the top level of the payload
  • slots: Each slot in your bot's domain and its value at the current time
  • latest_message: The attributes of the latest message
  • followup_action: The action called was a forced follow up action
  • paused: Whether the conversation is currently paused
  • events: A list of all previous events
  • active_loop: The name of the currently active form, if any
  • active_form: (Deprecated, replaced by active_loop) The name of the currently active form, if any
  • latest_action_name: The name of the last action the bot executed
  • stack: Current dialogue stack

In the example case, your custom action uses the value of the location slot (if it is set) to get the weather forecast.

domain

The domain is a json representation of your domain.yaml file. It is unlikely that a custom action will refer to its contents, as they are static and do not indicate the state of the conversation.

You can control if an action should receive a domain or not. Visit selective-domain

Caching the domain object for improved performance

From version 3.9.0 onwards, Rasa action server caches the domain object in the action server. This is done to avoid sending the domain object over the network for every request. Check the domain_digest field to learn more about the domain file used to generate the domain object.

domain_digest

Used to check if the cached domain object in the action server is up-to-date. Contains the name of the trained model file which is loaded by Rasa.

Starting from version 3.9.0, Rasa SDK caches the domain object in the action server, so that it does not need to be sent with every request. To make sure that the action server is aware of the latest domain changes, you can send the domain_digest field in the request. Alongside domain_digest, you can also send the domain object in the request. The action server will compare the digest with the one it has cached. In case the digests (the one retained in Action server and the one sent over network) do not match, the Action server will act as follows:

  • If domain was not sent in the request, it will respond with a RETRY (449) response code in case of HTTP protocol or a NOT_FOUND error code with DOMAIN_NOT_FOUND error detail in case of gRPC protocol. In the next request, Rasa server will send the domain object.
  • If domain was sent in the request, the action server will update the cached domain object with the new domain object sent in the request.

version

This is the version of the Rasa server. A custom action is also unlikely to refer to this, although you might use it in a verification step if your action server is only compatible with certain Rasa versions.

Custom Action Output

The Rasa server expects a dictionary of events and responses as a response to a custom action call.

events

Events are how your action server can influence the conversation. In the example case, your custom action should store the maximum temperature in the temperature slot, so it needs to return a slot event. To set the slot and do nothing else, your response payload would look like this:

{
"events": [
{
"event": "slot",
"timestamp": null,
"name": "temperature",
"value": "30"
}
],
"responses": []
}

Note that events will be applied to the tracker in the order you list them; with slot events, the order won't matter, but with other event types it can.

responses

A response can be of any of the response types described in the documentation on rich responses. See the response sample of the API spec for the expected formats.

In the example case, you want to send the user a message with the weather forecast. To send a regular text message, the response payload would look like this:

{
"events": [
{
"event": "slot",
"timestamp": null,
"name": "temperature",
"value": "30"
}
],
"responses": [
{
"text": "This is your weather forecast!"
}
]
}

When this response is sent back to the Rasa server, Rasa will apply the slot event and two responses to the tracker, and return both messages to the user.

Special Action Types

There are special action types that are automatically triggered under certain circumstances, namely default actions and slot validation actions. These special action types have predefined naming conventions that must be followed to maintain the automatic triggering behavior.

You can customize a default action by implementing a custom action with exactly the same name. Please see the docs on default actions for the expected behavior of each action.

Slot validation actions are run on every user turn, depending on whether a form is active or not. A slot validation action that should run when a form is not active must be called action_validate_slot_mappings. A slot validation action that should run when a form is active must be called validate_<form name>. These actions are expected to return SlotSet events only and to behave like the Rasa SDK ValidationAction class and FormValidationAction class respectively.