Using unfeaturized slot as list

Hello, How can I use a slot that holds a list of variable length that is given by user? For example the bot asks: " How many elements ?", then the user inputs a number and then the bot asks exactly that number of times for an element ( the full text entered by the user is the element). I have tried FormAction with the following: a slot with the number of elements, then a slot for one element and a slot with initial value []. In the validation function for one element I force a reset to none until the bot asks the given number of times and I want in this function to add the values to the other slot that holds the list. I attempted to append like in normal Python lists but the slot remains []. How can this effect be achieved? I have spent a lot of time but can’t figure this out.

Tried using: docs_list: type: unfeaturized initial_value: []

or

docs_list: type: list initial_value: []

def validate_one_doc(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
) -> Dict[Text, Any]:
    """Validate language value."""

    if len(tracker.get_slot("docs_list")) == int(tracker.get_slot("docs_no")) - 1:
        tracker.slots["docs_list"].append(value)
        return {"one_doc": value}
    else:
        # trick to build a list of docs
        tracker.slots["docs_list"].append(value)
        return {"one_doc": None}
1 Like

Hi @adikinzor!

You need to return the slot with the updated value in order to set it. Try the following:

 def validate_one_doc(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
) -> Dict[Text, Any]:
    """Validate language value."""

    if len(tracker.get_slot("docs_list")) == int(tracker.get_slot("docs_no")) - 1:
        new_doc_list = tracker.get_slot("docs_list").append(value)
        return {"one_doc": value, "docs_list": new_doc_list}
    else:
        # trick to build a list of docs
        new_doc_list = tracker.get_slot("docs_list").append(value)
        return {"one_doc": None, "docs_list": new_doc_list}

Thanks, this seems to work but list concatenation is needed instead of append because it returns None. Managed to obtain expected behavior with:

docs_list:
    type: list
    initial_value: []

and

def validate_one_doc(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
) -> Dict[Text, Any]:
    """Validate language value."""

    if len(tracker.get_slot("docs_list")) == int(tracker.get_slot("docs_no")) - 1:
        # valid
        new_doc_list = tracker.get_slot("docs_list") + [value]
        return {"one_doc": value, "docs_list": new_doc_list}
    else:
        # trick to build a list of docs
        new_doc_list = tracker.get_slot("docs_list") + [value]
        return {"one_doc": None, "docs_list": new_doc_list}
2 Likes

Hi Adrian Florin. Does the conversation get affected by the slot type. I see that unfeaturized type only does not affect conversation. So, I am wondering what happens as you are using list type for slot.