RASA Framework: Wrong validate function triggered after input in form

66 Views Asked by At

I am working on RASA Chatbot and have form that should ask for 2 values, productID and level.

I wrote following action based on RASA documentation and examples that should be executed after every response while form is active and check if given values make sense or not.

class ValidateSetupNoEnititesForm(FormValidationAction):
def name(self) -> Text:
    return "validate_setup_no_enitites_form"

@staticmethod
def level_db() -> List[Text]:
    """Database of supported levels"""

    return ["One",
            "Two",
            "Three",
            "Four",
            "Five",
            "Six",
            "1",
            "2",
            "3",
            "4",
            "5",
            "6"]


@staticmethod
def productid_db() -> List[Text]:
    """Database of supported product ids"""

    return ["one zero zero",
            "one zero one",
            "one zero two",
            "one zero three",
            "one zero four",
            "one hundred",
            "one hundred one",
            "one hundred two",
            "one hundred three",
            "one hundred four",
            "hundred",
            "hundred one",
            "hundred two",
            "hundred three",
            "hundred four", 
            "100",
            "101",
            "102",
            "103",
            "104"]

@staticmethod
def is_int(string: Text) -> bool:
    """Check if a string is an integer."""
    try:
        int(string)
        return True
    except ValueError:
        return False

def validate_level(
    self,
    level: Any,
    dispatcher: CollectingDispatcher,
    tracker: Tracker,
    domain: DomainDict,
    ) -> Dict[Text, Any]:

    if level.lower() in self.level_db() or level in range(1, 7):
        # validation succeeded, set the value of the "level" slot to value
        dispatcher.utter_message(f'Level is valid: {level}')
        return {"level": level}
    else:
        # validation failed, set this slot to None so that the
        # user will be asked for the slot again
        dispatcher.utter_message(f'Level not valid {level}')
        return {"level": None}

def validate_productID(
    self,
    productID: Any,
    dispatcher: CollectingDispatcher,
    tracker: Tracker,
    domain: DomainDict,
    ) -> Dict[Text, Any]:
    
    if (self.is_int(productID) and int(productID) in range(100, 105)) or (productID.lower() in self.productid_db()):
        # validation succeeded, set the value of the "productID" slot to value
        dispatcher.utter_message(f'ID valid: {productID}')
        return {"productID": productID}
    else:
        # validation failed, set this slot to None so that the
        # user will be asked for the slot again
        dispatcher.utter_message(f'ID not valid: {productID}')
        return {"productID": None}

And form as well as entities are defined in domain as:

entities:
- productID
- level
slots:
  productID:
    type: text
    influence_conversation: false
    mappings:
    - type: from_entity
      entity: productID
  level:
    type: text
    influence_conversation: false
    mappings:
    - type: from_entity
      entity: level
      
forms:
  setup_no_enitites_form:
    required_slots:
        - productID
        - level

And these 2 utter's are used to ask for input:

  utter_ask_setup_no_enitites_form_productID:
  - text: "For what ID do you want to make change?"
  utter_ask_setup_no_enitites_form_level:
  - text: "Enter desired level (1-6)"

The issue that I have is that, first chatbot asks me to provide ID and once I do it, it checks it as level and gives response as below:

For what ID do you want to make change?
Your input ->  100                                                                                                                    
Level not valid 100

Did I forget to do/include something?

0

There are 0 best solutions below