@ tonysinghmss Thanks for your reply, But as I told to Julian, I want to deactivate my form without defining a deactivate_intent
. I want to handle the context switch. For example, a user is in the middle of a restaurant form. Bot ask him about something to find the value of REQUESTED_SLOT
(for example cuisine
) but the user reply like this:
‘Can you get me a taxi, please?’
User changes the topic. I want to deactivate restaurant form, then switch to taxi form and start to ask him about the location.
I can’t handle it using unhappy stories I have at least 50 other intents. So writing tons of stories is impossible for me!
I solved my problem by changing a couple of lines of 4 files of rasa
and rasa_sdk
libraries. But I don’t like to change libraries!
@ gaurangubhatt As Julian and Manishankar mentioned:
- Define your
deactivation_intent
- Define your custom form
- Inside
validate
function of your form, check the intent of last message and deactivate your form if the intent of last message wasdeactivate_intent
:
def validate(
self,
dispatcher: "CollectingDispatcher",
tracker: "Tracker",
domain: Dict[Text, Any],
) -> List[EventType]:
"""Extract and validate value of requested slot.
If nothing was extracted reject execution of the form action.
Subclass this method to add custom validation and rejection logic
"""
# extract other slots that were not requested
# but set by corresponding entity or trigger intent mapping
slot_values = self.extract_other_slots(dispatcher, tracker, domain)
# extract requested slot
slot_to_fill = tracker.get_slot(REQUESTED_SLOT)
if slot_to_fill:
slot_values.update(self.extract_requested_slot(dispatcher, tracker, domain))
if not slot_values:
if tracker.latest_message.get("intent", {}).get("name")=='deactivation':
self.deactivate()
# reject to execute the form action
# if some slot was requested but nothing was extracted
# it will allow other policies to predict another action
raise ActionExecutionRejection(
self.name(),
"Failed to extract slot {0} "
"with action {1}"
"".format(slot_to_fill, self.name()),
)
logger.debug("Validating extracted slots: {}".format(slot_values))
return self.validate_slots(slot_values, dispatcher, tracker, domain)