Actions | Rasa Documentation
Build your first agent in just a few minutes with Rasa Copilot.
When a Rasa assistant calls a custom action
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:
- the action server is started with HTTPS enabled
- the certificate is signed by a trusted CA
- the server certificate has a list of hosts set correctly
GRPC Protocol
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:
- the action server is started with secure connection enabled
- the certificate is signed by a trusted CA
- the server certificate has list of hosts set correctly
Streaming custom actions over gRPC
When the output channel supports streaming and the action server is reached over gRPC, Rasa opens the WebhookStream server-streaming RPC instead of the unary Webhook call. The SDK yields WebhookStreamEvent messages (chunk_start, chunk, chunk_end, final_result, or error) as the action produces them. Rasa forwards each chunk to the output channel in real time.
Rasa activates the streaming path only when both the action executor and the output channel report streaming support (supports_streaming). If either side does not, Rasa falls back to the non-streaming path even when your action code calls stream_start / stream_chunk / stream_end.
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.
- Input Layout
- JSON Example
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 }
}
{
"next_action": "action_tell_weather",
"sender_id": "2687378567977106",
"tracker": {
"sender_id": "2687378567977106",
"slots": {
"location": null,
"temperature": null
},
"latest_message": {
"text": "/ask_weather",
"intent": {
"name": "ask_weather",
"confidence": 1
},
"intent_ranking": [{
"name": "ask_weather",
"confidence": 1
}],
"entities": []
},
"followup_action": null,
"paused": false,
"events": [{
"event": "action",
"timestamp": 1599850576.654908,
"name": "action_session_start",
"policy": null,
"confidence": null
}, {
"event": "session_started",
"timestamp": 1599850576.654916
}, {
"event": "action",
"timestamp": 1599850576.654928,
"name": "action_listen",
"policy": null,
"confidence": null
}, {
"event": "user",
"timestamp": 1599850576.655345,
"text": "/ask_weather",
"parse_data": {
"text": "/ask_weather",
"intent": {
"name": "ask_weather",
"confidence": 1
},
"intent_ranking": [{
"name": "ask_weather",
"confidence": 1
}],
"entities": []
},
"input_channel": "facebook",
"message_id": "3f2f2317dada4908b7a841fd3eab6bf9",
"metadata": {}
}],
"active_form": {},
"latest_action_name": "action_listen"
},
"domain": {
"config": {
"store_entities_as_slots": true
},
"session_config": {
"session_expiration_time": 60,
"carry_over_slots_to_new_session": true
},
"intents": [{
"greet": {
"use_entities": true
}
}, {
"ask_weather": {
"use_entities": true
}
}],
"entities": [],
"slots": {
"location": {
"type": "rasa.core.slots.UnfeaturizedSlot",
"initial_value": null,
"auto_fill": true
},
"temperature": {
"type": "rasa.core.slots.UnfeaturizedSlot",
"initial_value": null,
"auto_fill": true
}
},
"responses": {
"utter_greet": [{
"text": "Hey! How are you?"
}]
},
"actions": ["action_tell_weather", "utter_greet"],
"forms": []
},
"version": "2.0.0"
}
## 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.
### `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.
### `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
- `latest_action_name`: The name of the last action the bot executed
- `stack`: Current dialogue stack
### `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.
### `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.
### `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.
```json
{
"events": [{
"event": "slot",
"timestamp": null,
"name": "temperature",
"value": "30"
}],
"responses": []
}
responses
A response can be of any of the response types. In the example case, you want to send the user a message with the weather forecast.
{
"events": [{
"event": "slot",
"timestamp": null,
"name": "temperature",
"value": "30"
}],
"responses": [{
"text": "This is your weather forecast!"
}]
}
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.