Rasa Core version: 0.8.5
Python version: 3.6.4
Operating system (windows, osx, ...): OSX
Issue:
How to restart and empty all slots after conversation. I tried "action_restart" at the end of every story, but it is not working. Also tried to make some custom action (action_slot_reset) for slot reseting after "utter_bye", but it isn't working also.
Content of domain file (if used & relevant):
class AllSlotsReset(Action):
def name(self):
return 'action_slot_reset'
def run(self, dispatcher, tracker, domain):
return[AllSlotsReset()]
while running online training script it doesn't show any errors, only after utter_bye with code:
raise ValueError("event to log must be an instance "
ValueError: event to log must be an instance of a subclass of Event.
Hmm what happens when you add action_restart at the end of the story?
Hi, nothing happens. Here is the example of story:
## Pay 25 $
* pay{"value": "25", "currency": "$"}
- slot{"value": "25"}
- slot{"currency": "$"}
- action_check_person
- utter_person
* inform{"person": "marina"}
- slot{"person": "marina"}
- utter_payconfirm
* confirm
- utter_payconfirmed
- utter_anythingelse
* bye
- utter_bye
- export
- action_restart
User should end conversation after "Anything else" if he says "no, thank you". Then if he wants to pay to someone else, he should say "Pay to John" and bot should again ask him for value (like in every new dialog), but slot value:25 is filled from previous dialogue..
I want to restart all slots after bot's utter_bye because user completed his payment, and to start a brand new conversation with all slots empty.
Is action_restart at the end of all your stories?
EDIT: Just read your question more carefully, and I see you've tried that.
Are you importing AllSlotsReset from rasa_core.events? It looks like the class you're returning is your own custom action, instead of the rasa_core event. I would consider changing the name of your custom action to something less conflicting; also, confirm you're returning the AllSlotsReset event.
from rasa_core.events import AllSlotsReset
from rasa_core.events import Restarted
class Restarted(Action):
def name(self):
return 'action_restarted'
def run(self, dispatcher, tracker, domain):
return[Restarted()]
class AllSlotsReset(Action):
def name(self):
return 'action_slot_reset'
def run(self, dispatcher, tracker, domain):
return[AllSlotsReset()]
This is part of actions.py code
You still have naming issues. Try this, and make corrections in domain and stories as needed:
class ActionRestarted(Action):
def name(self):
return 'action_restarted'
def run(self, dispatcher, tracker, domain):
return[Restarted()]
class ActionSlotReset(Action):
def name(self):
return 'action_slot_reset'
def run(self, dispatcher, tracker, domain):
return[AllSlotsReset()]
Though your - action_restart at the end of your stories should do this job. If you'd like a resolution there, can you paste/upload your stories?
# 200 to Nikola
* pay{"value": "200", "person": "nikola"}
- slot{"value": "200"}
- slot{"person": "nikola"}
- action_check_currency
- utter_currency
* inform{"currency": "$"}
- slot{"currency": "$"}
- utter_payconfirm
* confirm
- utter_payconfirmed
- utter_anythingelse
* bye
- utter_bye
- export
- action_restart
## Pay 25 $
* pay{"value": "25", "currency": "$"}
- slot{"value": "25"}
- slot{"currency": "$"}
- action_check_person
- utter_person
* inform{"person": "marina"}
- slot{"person": "marina"}
- utter_payconfirm
* confirm
- utter_payconfirmed
- utter_anythingelse
* bye
- utter_bye
- export
- action_restart
etc ..
this method doesn't work, that's why i tried with custom actions
ok, i added Action after class and before name of the action, and it seems to work now with this method. Thank you for pointing that out.
_you can close this_
Someone else will have to close it. I'm just a guy.
Hi, thanks @foxjr , this solution worked for me. Going a bit further... any idea how to reset all slots...except one?
@basque21 You're best off calling a custom action whenever you want that behavior. It should contain the logic:
for slot in tracker.slots:
if slot != "foo":
SlotSet(slot, None)
Where _foo_ is the slot you want to preserve. In your stories, just name the custom action at the appropriate time, and you should be good.
And by the way, the action_restart resets the tracker, so you lose your state altogether, which is different than resetting slots.
@foxjr i tried:
class ActionRenew(Action):
def name(self):
return 'action_renew'
def run(self, dispatcher, tracker, domain):
for slot in tracker.slots:
if slot != "foo":
SlotSet(slot, None)
and it's not working...it doesn't restart the slots.
EDIT: if I do: return SlotSet('foo', None) it sets this slots to None, but I don't know how to do it with more than one slot...
I forgot a step:
return_slots = []
for slot in tracker.slots:
if slot != "foo":
return_slots.append(SlotSet(slot, None))
return return_slots
You need to return a list of SlotSets in order to set multiple slots.
This worked! thank you very much!!
No problem!
I just noticed that there is an action_restart. I assume this will reset the bot, as if it knew nothing. This is handy if you made a successful request, without the requirement to keep any previous slots.
Now I am using online training, but whenever I chose action_restart the story is lost in the generated markdown file. Is this a bug? I though action_restart is somewhat useless in the first place, but now I think it is a bug or the online training.
What do you think?
hello foxjr,
i have tried this but not getting any error but slots are not resetting can help me to figure out this issue
def run(self, dispatcher, tracker, domain):
global PAGE_INSTANCE_ID, PREVIOUS_INTENT
intent = tracker.latest_message.get("intent", {}).get("name")
PAGE_INSTANCE_ID = intent
PREVIOUS_INTENT = intent
# Reset slots
reset_specific_slots = []
if PREVIOUS_INTENT != intent:
for x in tracker.slots:
if REQUESTED_SLOT != x and x not in self.all_slots():
reset_specific_slots.append(SlotSet(x, None))
print('reset_specific_slots: ', reset_specific_slots)
in fallback intent i have write
if current_action is not None and PREVIOUS_INTENT != current_action:
if intent == 'add_bank':
dispatcher.utter_template('utter_change_{}'.format(intent), tracker)
return [AllSlotsReset(), Form(name='add_bank'),
FollowupAction(name='action_done_add_bank')]
elif intent == 'manage_bank':
dispatcher.utter_template('utter_change_{}'.format(intent), tracker)
return [AllSlotsReset(), Form(name='manage_bank'),
FollowupAction(name='action_done_manage_bank')]
I forgot a step:
return_slots = [] for slot in tracker.slots: if slot != "foo": return_slots.append(SlotSet(slot, None)) return return_slotsYou need to return a list of
SlotSets in order to set multiple slots.
hello foxjr,
i have tried this but not getting any error but slots are not resetting can help me to figure out this issuedef run(self, dispatcher, tracker, domain):
global PAGE_INSTANCE_ID, PREVIOUS_INTENT
intent = tracker.latest_message.get("intent", {}).get("name")
PAGE_INSTANCE_ID = intent
PREVIOUS_INTENT = intentReset slots
reset_specific_slots = []
if PREVIOUS_INTENT != intent:
for x in tracker.slots:
if REQUESTED_SLOT != x and x not in self.all_slots():
reset_specific_slots.append(SlotSet(x, None))
print('reset_specific_slots: ', reset_specific_slots)
in fallback intent i have writeif current_action is not None and PREVIOUS_INTENT != current_action:
if intent == 'add_bank':
dispatcher.utter_template('utter_change_{}'.format(intent), tracker)
return [AllSlotsReset(), Form(name='add_bank'),
FollowupAction(name='action_done_add_bank')]
elif intent == 'manage_bank':
dispatcher.utter_template('utter_change_{}'.format(intent), tracker)
return [AllSlotsReset(), Form(name='manage_bank'),
FollowupAction(name='action_done_manage_bank')]I forgot a step:
return_slots = [] for slot in tracker.slots: if slot != "foo": return_slots.append(SlotSet(slot, None)) return return_slotsYou need to return a list of
SlotSets in order to set multiple slots.
i want to do if i am one intent then call for new intent then all slots value should be reset
e.g. I call for an intent "Add Bank" fill one slot then move to another intent "Manage Bank" then slots value should be reset
please create a new issue
Most helpful comment
I forgot a step:
You need to return a list of
SlotSets in order to set multiple slots.