Hi @stephens got that to work, thanks. I am trying to extract the departure date from the flight and inform_depart_date intent and return date from the inform_return_date intent. Since depart date and return date are set separately through two different intents the duckling time entity overwrites the previous time value, say i specify I want to depart on August 21st then time slot gets set to 2020-08-21T00:00:00 and in another intent (inform_return_date) I say I want to return on August 25th then time gets overwritten to 2020-08-25T00:00:00. To fix this I created two extra text slots depart_date and return_date which map to the duckling time entity. I also wrote validate functions for both departure date and return date that set these dates from the time entity. Here are the validate functions I have written
def validate_return_date(self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate return date."""
time_entities = [e for e in tracker.latest_message["entities"] if e["entity"] == "time"]
if tracker.latest_message['intent'].get('name') == "flight" and len(time_entities) > 1:
[return_date, return_time, *extra] = re.split(r"[T,+,.]",time_entities[-1]["value"])
depart_date = datetime.datetime.strptime(tracker.get_slot("depart_date"),"%Y-%m-%d").date()
return_date = datetime.datetime.strptime(return_date,"%Y-%m-%d").date()
if return_date < depart_date:
dispatcher.utter_message("Return date should be after the departure date")
SlotSet("return_date",None)
SlotSet("time",None)
return {"return_date": None}
else:
SlotSet("return_date", str(return_date))
return {"return_date": str(return_date)}
else:
[return_date, return_time, *extra] = re.split(r"[T,+,.]",tracker.get_slot("time"))
return_date = datetime.datetime.strptime(return_date,"%Y-%m-%d").date()
depart_date = datetime.datetime.strptime(tracker.get_slot("depart_date"),"%Y-%m-%d").date()
if return_date < depart_date:
dispatcher.utter_message("You need to choose a return date after the departure date")
SlotSet("return_date",None)
SlotSet("time",None)
return {"return_date": None}
else:
SlotSet("return_date", str(return_date))
return {"return_date": str(return_date)}
def validate_depart_date(self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate departure date."""
[depart_date, depart_time, *extra] = re.split(r"[T,+,.]",tracker.get_slot("time"))
depart_date = datetime.datetime.strptime(depart_date,"%Y-%m-%d").date()
now = datetime.datetime.now().date()
if depart_date < now:
dispatcher.utter_message("Sorry you need to choose date in the present for me to search for flights")
SlotSet("depart_date",None)
SlotSet("time",None)
return {"depart_date": None}
else:
SlotSet("depart_date", str(depart_date))
return {"depart_date": str(depart_date)}
In the slot mappings function I have defined the following
"depart_date": self.from_entity(entity="time",intent=["flight","inform_departure_date"]),
"return_date": self.from_entity(entity="time", intent=["inform_return_date"])
This fixed the 2 time slots problem but now there is another problem. Only the time slot gets set when the entity is detected in the flight intent, the depart_date doesn’t get set. This leads to slot showing as missing and the utter_ask_depart_date question is asked (even though departure date is already specified) when the form action is activated. I tried creating a validate function for time but it didn’t work and the same problem persists.
def validate_time(self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate duckling time entity"""
latest_intent = tracker.latest_message['intent'].get('name')
if latest_intent == "flight" or latest_intent == "inform_departure_date":
[depart_date, depart_time, *extra] = re.split(r"[T,+,.]",tracker.get_slot("time"))
depart_date = datetime.datetime.strptime(depart_date,"%Y-%m-%d").date()
now = datetime.datetime.now().date()
if depart_date < now:
dispatcher.utter_message("Sorry you need to choose date in the present for me to search for flights")
SlotSet("depart_date",None)
SlotSet("time",None)
return {"depart_date": None}
else:
SlotSet("depart_date", str(depart_date))
return {"depart_date": str(depart_date)}
Is there something you can suggest to fix this?