Hey… I have an issue where, when once a form is running, if i provide more than one entities to it through an input, the bot extracts the entities, however through SlotSet() sets only the last entity extracted, and hence only validates that slot. Here’s my actions file
from typing import Any, Text, Dict, List, Union, Optional from rasa_sdk import Action, Tracker, FormValidationAction from rasa_sdk.events import SlotSet from rasa_sdk.executor import CollectingDispatcher from dateutil.parser import parse from datetime import date, time
class ActionHelloWorld(Action):
def name(self) -> Text:
return "action_say_data"
def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
travel_mode = tracker.get_slot("travel_mode")
journey_type = tracker.get_slot("journey_type")
source = tracker.get_slot("source")
destination = tracker.get_slot("destination")
departure_date = tracker.get_slot("departure_date")
departure_time = tracker.get_slot("departure_time")
arrival_date = tracker.get_slot("arrival_date")
arrival_time = tracker.get_slot("arrival_time")
if journey_type in ["1", "one", "1-way", "1 way", "one way", "one-way", "single", "one-way trip", "one trip", "1 way trip", "single trip", "one way trip", "one-way trip"]:
dispatcher.utter_message(text=f"You are travelling from {source} to {destination} via {travel_mode}. The journey type is a {journey_type} trip. Your departure journey will commence on {departure_date} at {departure_time}.")
else:
dispatcher.utter_message(text=f"You are travelling from {source} to {destination} via {travel_mode}. The journey type is a {journey_type} trip. Your departure journey will commence on {departure_date} at {departure_time} and your arrival journey will begin on {arrival_date} at {arrival_time}.")
dispatcher.utter_message(text="Have a nice journey !! :)")
return []
class ValidateTravelForm(FormValidationAction):
def name(self) -> Text:
return "validate_travel_form_1"
def validate_journey_type(self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
journey_type = tracker.get_slot("journey_type")
if journey_type in ["1", "one", "1-way", "1 way", "one way", "one-way", "single", "one-way trip", "one trip", "1 way trip", "single trip", "one way trip", "one-way trip"]:
dispatcher.utter_message(f"Journey set to one way")
return {"journey_type": journey_type}
elif journey_type in ["2", "two", "2-way", "2 way", "two way", "two-way", "round", "round way", "round trip", "return", "return trip", "two trip", "2 way trip", "two way trip", "two-way trip"]:
dispatcher.utter_message(f"Journey set to round trip")
dispatcher.utter_message(f"aaaa")
return {"journey_type": journey_type}
else:
dispatcher.utter_message("Invalid trip type!!")
return {"journey_type": None}
async def required_slots(
self,
domain_slots: List[Text],
dispatcher: "CollectingDispatcher",
tracker: "Tracker",
domain: Dict[Text, Any]
) -> List[Text]:
required_slots = domain_slots.copy()
journey_type = tracker.get_slot("journey_type")
if journey_type in ["1", "one", "1-way", "1 way", "one way", "one-way", "single", "one-way trip", "one trip", "1 way trip", "single trip", "one way trip", "one-way trip"]:
required_slots.remove("arrival_date")
required_slots.remove("arrival_time")
return required_slots
def validate_travel_mode(self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
travel_mode = tracker.get_slot("travel_mode")
travel_mode_list = ["car", "cab", "taxi", "bus", "road", "train", "rail", "railway", "air", "plane", "flight", "aeroplane", "airplane", "sea", "water", "ship", "boat", "cruise"]
if travel_mode in travel_mode_list:
return {"travel_mode": travel_mode}
else:
dispatcher.utter_message(text=f"Invalid Travel Mode: {travel_mode}. Please make sure there are no typos.")
dispatcher.utter_message(f"78578558")
return {"travel_mode": None}
def validate_source( self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
source = tracker.get_slot("source")
return {"source": source}
def validate_departure_date(self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
departure_date = tracker.get_slot("departure_date")
dispatcher.utter_message(text=f"datedatedate")
today_date = date.today()
try:
departure_date = parse(departure_date)
departure_date = departure_date.date()
except:
dispatcher.utter_message(text=f"Invalid Departure Date: {departure_date} Please make sure there are no typos.")
return {"departure_date": None}
if departure_date > today_date:
return {"departure_date": departure_date}
else:
dispatcher.utter_message(text="Invalid Departure Date. Departure Date cannot be before the Current Date (Today).")
return {"departure_date": None}
def validate_departure_time(self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
departure_time = tracker.get_slot("departure_time")
dispatcher.utter_message(text=f"timetimetime")
try:
departure_time = departure_time.split(' ')[0]
if ':' not in departure_time:
departure_time = departure_time + ':00'
departure_time = parse(departure_time)
departure_time = departure_time.time()
return {"departure_tine": departure_time}
except:
dispatcher.utter_message(text="Invalid Departure Time. Please make sure there are no typos.")
return {"departure_time": None}
def validate_destination( self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
source = tracker.get_slot("source")
destination = tracker.get_slot("destination")
if destination == source:
dispatcher.utter_message(text="Invalid destination. Source and Destinations cannot be the same place.")
return {"destination": None}
else:
return {"destination": destination}
def validate_arrival_date(self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
departure_date = tracker.get_slot("departure_date")
arrival_date = tracker.get_slot("arrival_date")
dispatcher.utter_message(f"dddd")
try:
departure_date = parse(departure_date)
departure_date = departure_date.date()
arrival_date = parse(arrival_date)
arrival_date = arrival_date.date()
except:
dispatcher.utter_message(text=f"Invalid Arrival Date: {arrival_date} Please make sure there are no typos.")
return {"arrival_date": None}
if arrival_date > departure_date:
return {"arrival_date": arrival_date}
else:
dispatcher.utter_message(text="Invalid Arrival Date. Arrival Date cannot be before the Departure Date.")
return {"arrival_date": None}
def validate_arrival_time(self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
arrival_time = tracker.get_slot("arrival_time")
dispatcher.utter_message(f"eeee")
try:
arrival_time = arrival_time.split(' ')[0]
if ':' not in arrival_time:
arrival_time = arrival_time + ':00'
arrival_time = parse(arrival_time)
arrival_time = arrival_time.time()
return {"arrival_time": arrival_time}
except:
dispatcher.utter_message(text="Invalid Arrival Time. Please make sure there are no typos.")
return {"arrival_time": None}
def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
return {
"source": [
self.from_entity(entity="location"),
],
"destination": [
self.from_entity(entity="location"),
],
"departure_date": [
self.from_entity(entity="date"),
],
"departure_time": [
self.from_entity(entity="time"),
],
"arrival_date": [
self.from_entity(entity="date"),
],
"arrival_time": [
self.from_entity(entity="time"),
]
}
I want it to be able to extract multiple slots at once, even when inside the form. Can someone please help me out… Thanks