Bug in Form works first time , second time fails to pick up entities

I want to accept two numbers in a form. It works fine when it fills the slot first time. Next time user asks, it goes back to the question of what is slot_1? Is that a bug?

@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
    return [slot_1", "slot_2"]

def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:

    return {
        "slot_1": [
            self.from_entity(
                entity="number", intent=["test"]
            ),
        ]
        ,
        "slot_2": [
            self.from_entity(
                entity="number", intent=["test"]
            ),
        ],
    }

@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_slot_1(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
) -> Dict[Text, Any]:

    if isinstance(value, list):
        if len(value) == 2:
            if self.is_int(value[0]) and int(value[0]) > 0 and self.is_int(value[1]) and int(value[1]) > 0 :
                return {"slot_1": value[0], "slot_2": value[1]}
        else:
            return {"slot_1": None, "slot_2": None}

    if self.is_int(value) and int(value) > 0:
        return {"slot_1": value}
    else:
        dispatcher.utter_message(text="slot not valid?")
        # validation failed, set slot to None
        return {"slot_1": None}

def validate_slot_2(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
) -> Dict[Text, Any]:
    if self.is_int(value) and int(value) > 0:
        return {"slot_2": value}
    else:
        dispatcher.utter_message(text="slot2 not valid?")
        # validation failed, set slot to None
        return {"slot_2": None}

In the submit function: return [SlotSet(“slot_1”, None)] + [SlotSet(“slot_2”, None)]

its a strange behaviour that it works fine first time.

class FormAction(Action): should_fill_entity_slot = ( other_slot_mapping[“type”] == “from_entity” and other_slot_mapping.get(“entity”) == slot and self.intent_is_desired(other_slot_mapping, tracker) )

I think here it looks for the entity name to be same as slot name? like the entity name is “number”, it is trying to match exactly with that name which is the issue i think?

The way i fixed this is:

“number”: [ self.from_entity( entity=“number”, intent=[“test”] ), ],

I added the entity name itself as a slot and then used def validate_number() to populate the entities. Please confirm this is a bug and should raise in github to fix this.

Hi @sibbsnb,

can you try this?

def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:

    return {
        "slot_1": self.from_text(),
        "slot_2": self.from_text()
           }

There is a problem in your slot filling as bot is unable to distinguish between slot 1 and slot 2 as both are same. When you try to fill slot 2, bot understands it as if you are trying to fill slot 1 and hence it asks que for filling slot 1. It’s not a bug

Do checkout slot mappings for more info on slot mappings for understanding 3 ways to map a slot.

It works first time not other times. I understand it is same slot types which is why one slot both numbers comes as a list which is fine. That itself doesnt happen here.

There are a couple of approaches you can use for this.

  • Use a List slot and extract the list of values via tracker.get_slot("number").
  • Use the tracker.get_latest_entity_values("number") call to
2 Likes

ended up using the List slot. Thanks.