Filling and validating a single slot through form

Hey everyone,

I’m having some trouble implementing a business logic that behaves like I want it to be and I was hoping someone could help me out. I’m rather new to rasa so apologies if this is rather basic, here’s what I’m trying to do: I have an Intent “get_productprice” that uses the value of the slot “term” to start a Custom Action which calls an API with the value. In the first stage the API checks if the value of term is a valid productnumber, if yes just return the Price based on the productnumber, if not the user is prompted to provide a valid productnumber.

At first my approach was to do it through custom actions but some recherche recommended to use forms instead, even though I only want to fill a single slot. I want to fill the term slot through 2 ways. The slot can be filled by the “get_productprice” intent itself, if a “term” entity is provided", and through a form if no entity is provided while sending the same intent.

So for example:

  • “Whats the price of my product 123” Where “123” is the provided term.
  • "Whats the price of my product?" Where the agent reacts by asking the user to provide a term.

    My problem is that the FormValidationAction is being called twice the form gets initially activated while providing a term entity along with the “get_productprice” intent. Otherwise the agent behaves as expected.

    This is my FormValidationAction:

    class ValidateTermForm(FormValidationAction):
      def name(self) -> Text:
        return "validate_term_form"
      def validate_term(
            value: Text,
            dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any],
      ) -> Dict[Text, Any]:
          """Validate term value."""
          if api.is_productnr(value):
            # validation succeeded, set the value of the "term" slot
            dispatcher.utter_message(text="term is productnr")
            return {"term": value}
            # validation failed, set this slot to None, meaning the
            # user will be asked for the slot again
            return {"term": None}

    This is my only story in stories.yml:

    • story: Productprice happy 1


      • intent: get_productprice


        • term: 221841
      • active_loop: term_form

      • action: term_form

      • active_loop: null

      • action: utter_slots_values

    And in rules.yml I have rules for the activation and deactivation for the term_form:

    • rule: activate term form for get productprice


      • intent: get_productprice
      • action: term_form
      • active_loop: term_form
    • rule: deactivate term form for get productprice


      • active_loop: term_form


      • action: term_form
      • active_loop: null
      • slot_was_set:
        • requested_slot: null
      • action: utter_slots_values

    Like I said, the agent mostly behaves like expected, except that the FormValidationAction is being called twice the first time the intent “get_productprice” has been classified along with a “term”-entity. So my question is basically how to make sure it is only being called once or I would really like to know if there’s another approach that is more suitable for having the user filling a slot that needs to be validated thereafter and requires the user to fill the slot with a value that is valid.

    I hope it’s clear what I’m trying to achieve. I’m really looking forward to your feedback and help, so thank you so much in advance!