Repository: RasaHQ/rasa
Pull request: Add docs for action and validation action together
Fixes https://github.com/RasaHQ/rasa/issues/10886


Problem statement:
Slot Mappings: custom validation action doesn't validate the slot when the slot is extracted by a different custom action
**Problem description**:
I tried testing to see if extracting a slot via a custom action inheriting from sdk `Action` class, then validating this extraction with a custom action inheriting from sdk `ValidationAction` works.

While the extraction works fine, the validation code doesn't seem to run, because the debug log shows the slot being set with the unvalidated value.

`actions.py` code:

```
from typing import Any, Text, Dict, List

from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import ValidationAction
from rasa_sdk.events import SlotSet


class SlotExtraction(Action):
    def name(self) -> Text:
        return "extract_residential_status"

    async def run(
            self, dispatcher, tracker: Tracker, domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        latest_intent = tracker.get_intent_of_latest_message()

        if latest_intent == "indicate_permanent_residence":
            return [SlotSet("residential_status", "resident")]
        elif latest_intent == "indicate_temporary_residence":
            return [SlotSet("residential_status", "tourist")]
        else:
            return []


class TestValidation(ValidationAction):
    @staticmethod
    def residence_db() -> List[Text]:
        """DB of supported residential statuses."""
        return ["resident", "tourist"]

    async def validate_residential_status(
            self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict
    ) -> Dict[Text, Any]:
        if slot_value in self.residence_db():
            return {"residential_status": slot_value.upper()}
        else:
            return {"residential_status": None}

```

The domain file includes:
```
  residential_status:
    type: categorical
    influence_conversation: false
    values:
      - resident
      - tourist
      - non-visitor
    mappings:
    - type: custom
      action: extract_residential_status

actions:
- action_validate_slot_mappings
- extract_residential_status
```

`nlu.yml` includes the checked intents:
```
- intent: indicate_permanent_residence
  examples: |
    - I am a citizen here.
    - I'm a permanent resident.
    - I live here.

- intent: indicate_temporary_residence
  examples: |
    - I don't live here.
    - I'm only visiting temporarily.
    - On vacation.
```

**Definition of Done**:
- [ ] validate if this method of slot filling via 2 different custom actions should work
- [ ] investigate and fix
- [ ] update docs that this method works as well

Hints from issue discussion:
This seems to work as expected for me and validated values are used in setting the slot. I've changed the action to have following:

```
if slot_value in self.residence_db():
     return {"residential_status": slot_value.upper() + '-VALIDATED'}
```

Shell logs show:

```
2022-02-11 17:30:05 DEBUG    rasa.core.processor  - Default action 'action_extract_slots' was executed, resulting in 1 events: SlotSet(key: residential_status, value: TOURIST-VALIDATED)
```

Does this make sense @ancalita ? I'll close if this is now working as expected.
@tayfun I couldn't reproduce it either, after trying this within and outside a form, seems to be working now 😄 
Could you please update docs though to state explicitly that this method works too (extraction by a regular custom action, then validation via SDK `ValidationAction`). I suppose it could go as a note [here](https://rasa.com/docs/rasa/slot-validation-actions), Melinda would know best actually.

Commit message: Add order of Action execution

Patch to review:
diff --git a/docs/docs/slot-validation-actions.mdx b/docs/docs/slot-validation-actions.mdx
index db1c71bd05fa..508f3d4ff6b0 100644
--- a/docs/docs/slot-validation-actions.mdx
+++ b/docs/docs/slot-validation-actions.mdx
@@ -7,6 +7,12 @@ abstract: A slot validation action is a special type of custom action, designed
 
 You can do custom extraction and validation of slot values by writing custom actions in three different ways.
 
+:::note Extraction and Validation can work together
+
+You can have an `Action` and a `ValidationAction` separately and both of these actions will be called from Rasa. For example, you can use a normal `Action` to create several events and a `ValidationAction` to validate that slot values are correct. In this scenario, `Action` will be called first and `ValidationAction` afterwards.
+
+:::
+
 ## `action_validate_slot_mappings`
 
 You can use the `action_validate_slot_mappings` action to define custom extraction and / or validation of slots that


Code review comments:
diff_hunk: @@ -7,6 +7,12 @@ abstract: A slot validation action is a special type of custom action, designed
 
 You can do custom extraction and validation of slot values by writing custom actions in three different ways.
 
+:::note Extraction and Validation can work together
+
+You can have an `Action` and a `ValidationAction` separately and both of these actions will be called from Rasa. For example, you can use a normal `Action` to create several events and a `ValidationAction` to validate that slot values are correct. In this scenario, `Action` will be called first and `ValidationAction` afterwards.
+
+:::
path: docs/docs/slot-validation-actions.mdx
text: @user1:
Is this no longer true?
> A slot validation action should only return `slot` and [`bot`](https://rasa.com/docs/action-server/events#bot) events.
Any other event type will be filtered out by the default action [`action_extract_slots`](./default-actions.mdx#action_extract_slots).


@author:
It is still true.

@user1:
In that case this needs some rephrasing, and I'd suggest moving it down to the end because at the beginning of the doc the user hasn't read about ValidationAction yet.

```suggestion
:::note Using different actions for extraction and validation

You can use both a regular custom action and `action_validate_slot_mappings` together to extract and validate a slot. For example, you can specify a regular custom action as the `action` for a `custom` slot mapping, and also add validation logic for the same slot to `action_validate_slot_mappings`. The custom action specified in the custom slot mapping will be called first, and `action_validate_slot_mappings` will be called afterwards.

:::
```

@author:
This is much better wording, thanks @user2