Setting Slots from Action in Form Rasa 2.x

I have a form with about 10 slots/fields in there. Some of those fields are address fields related to an school name. In the form, I’m prompting the user for the school name. I’d like to search our database for an address and populate the individual fields based on that if available, and in the validation, return all user input fields plus those returned from the DB lookup.

Actions and form definition from domain.yml: actions:

  • validate_tce_eval_form

forms:

tce_eval_form:

firstName:
  - type: from_entity
    entity: firstName
lastName:
  - type: from_entity
    entity: lastName
school_name: 
  - type: from_entity
    entity: school_name
school_program_name: 
  - type: from_text
    intent: school_program_name
school_program_grad_date:
  - type: from_text
    intent: school_program_grad_date

I’ve tried returning a list of slots(sets) in the validation action, but it does not set the slots. I’ve also tried creating individual extraction methods for the additional slots, but that too seems to fail to do what I desire.

Action class ActionTCEForm(FormValidationAction): def name(self) -> Text: return “validate_tce_eval_form”

    async def required_slots(
        self,
        slots_mapped_in_domain: List[Text],
        dispatcher: "CollectingDispatcher",
        tracker: "Tracker",
        domain: "DomainDict",
    ) -> Optional[List[Text]]:
        
        required_slots = slots_mapped_in_domain + ["schoool_phone", "school_addr_1", "school_city", "school_zip"]
        return required_slots

    def request_next_slot(self, dispatcher: CollectingDispatcher, tracker: Tracker,
                  domain: Dict[Text, Any]):
        print('Request next slot')
        for slot in self.required_slots(tracker):
            if self._should_request_slot(tracker, slot):
                if slot == 'school_name':
                    return [SlotSet('school_phone', '123-456-7890'), SlotSet['school_addr_1', '1234 Sesame Street']]
                if slot == 'school_phone':
                    dispatcher.utter_message(template='utter_ask_school_phone')

        return None

Anyone have some guidance on how to set values of slots based on a custom action for a given form?

For anyone else struggling with this, the code I needed, was in the validation of the form from which I’d set the additional slots.

Modifying the action to the following resolved my issue…:

class ActionTCEForm(FormValidationAction): def name(self) -> Text: return “validate_tce_eval_form”

    async def required_slots(
        self,
        slots_mapped_in_domain: List[Text],
        dispatcher: "CollectingDispatcher",
        tracker: "Tracker",
        domain: "DomainDict",
    ) -> Optional[List[Text]]:
        
        required_slots = slots_mapped_in_domain + ["schoool_phone", "school_addr_1", "school_city", "school_zip"]
        return required_slots

    def validate_school_name(self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        print("Setting school location fields")
        return {'school_phone': '123-456-7890', 'school_addr_1': '1234 Sesame Street'}

I found this solution via another post which led to Forms

Now that I’ve RTFM I’m good.

Great to see you found the solution for this and thank you so much for posting it here. I am sure other people will find it useful! :raised_hands: