I manage a fair bit of user state in actions - mostly flags and counters - so I can be smarter handling failure cases - e.g., if they don’t understand me one way, I’ll try to express it a different way. If they don’t get that, I might do a final way and if that fails, I’ll just set some default value.
So I have a user_obj slot that is a stringified json object that holds this stuff. Ideally, I’d like to just have a few functions exposed to actions that hide all the slot interface. e.g.,
if user_increment('shoe_size_fails') == 10:
dispatcher.utter_message("Seriously, I'm sick of asking you. What is your shoe size?")
where user_increment is a convenience function that adds 1 to the user property ‘shoe_size_fails’.
and then user_increment() manages the interface with the slot. Otherwise, I have to return the json string from these functions and then every action validate function has to remember to set the slot, etc. It just makes things much messier.
Is there a way that I can encapsulate the slot set in the user object functions? If not, I’ll probably just maintain it myself outside of Rasa, but I’d like to avoid if possible.
@akelad. Sort of it. It sets a property on an object that is stored in the unfeaturized user_obj slot. e.g., user_obj slot = ‘{“shoe_size_fails”:3, “user_level”:“pro”, etc.}’ In an action, when I need some user property, I deserialize this, get the property, modify the property and reserialize and store back into the user_obj slot.
I want to do this instead of creating a new unfeaturized slot for each user property because it really simplifies things for me. I am creating about 50 different models and each one will need to store its own user properties. With this approach, all I have to do is create a ‘user_obj’ unfeaturized slot in each model and then I can reuse the functions that set/get properties on that as I described above.
Otherwise, I have to maintain a list of unfeaturized slots for every model and then in my action code, I need to return [SlotSet()] for each of these. I know that doesn’t sound like that much, but it’s more clutter and it’s multiplied by 50 times.
To make this clean, I need to set the user_obj slot from a centralized function instead of having to return it as an event (yes, I could simply return the slot set event for the user_obj for each validate function, but that defeats the purpose).
Because I don’t know how to set a slot value directly (without returning an event), I have simply moved all this out of Rasa. I now just store this user_obj data in Redis (keyed by session id). It works fine, but I wouldn’t need to do this if I could just set the slot from a central function.