Hi Team,
Here code has written to dynamically fill the slot values from API with buttons. while it is executed and display the utter buttons twice, am wondering. does it cause due to bug in actions in validation events? or am i missing anything here? I have executed this logic in 1.7.X perfectly, we are trying to upgrade the rasa version to latest now. kindly help me , thanks in advance for all.
async def next_requested_slot( self, dispatcher: “CollectingDispatcher”, tracker: “Tracker”, domain: “DomainDict”, ) → Optional[EventType]:
required_slots = await self.required_slots(
self.slots_mapped_in_domain(domain), dispatcher, tracker, domain
)
if required_slots and required_slots == self.slots_mapped_in_domain(domain):
# If users didn't override `required_slots` then we'll let the `FormAction`
# within Rasa Open Source request the next slot.
return None
missing_slots = (
slot_name
for slot_name in required_slots
if tracker.slots.get(slot_name) is None
)
api_resp = {}
reg_loc = {}
for slot in required_slots:
if slot in ["region"]:
api_handler = ApiHandler()
if len(api_resp) <= 0:
api_resp = api_handler.get_call(tracker=tracker, api_text="vendor_api", params={})
# If response contains error then give the error msg as bot output
if "error_msg" in api_resp:
dispatcher.utter_message(api_resp["error_msg"], **tracker.slots)
return SlotSet(REQUESTED_SLOT, next(missing_slots, None))
# Collect the regions (as key) and related sites (as values) from response
if len(reg_loc) <= 0:
if "locations" in api_resp.keys() and len(api_resp["locations"]) > 0:
for item in api_resp["locations"]:
if item["regionId"] not in reg_loc.keys():
reg_loc[item["regionId"]] = [item["vendorSiteName"]]
else:
reg_loc[item["regionId"]].append(item["vendorSiteName"])
# Check if slot is region then select if it is single or give the option to chose from user
if slot == "region" or tracker.get_slot("region") is None:
reg_keys = list(reg_loc.keys())
# Check whether the region single/multiple to set slot
if len(reg_keys) > 0 and len(reg_keys) == 1:
tracker.slots["region"] = reg_keys[0]
else:
# Multiple regions select option as bot response
regions = dict((v, k) for k, v in self.regions().items())
buttons = []
for num in reg_keys:
buttons.append({"title": f"{regions[num]}", "payload": f"{regions[num]}"})
if len(buttons) > 0:
dispatcher.utter_message("Please select the region", buttons=buttons, **tracker.slots)
else:
dispatcher.utter_message("The selected vendor has no locations", **tracker.slots)
return None
return SlotSet(REQUESTED_SLOT, next(missing_slots, None))
elif slot == "site_location" and tracker.get_slot("region"):
reg_id = tracker.get_slot("region")
# Get locations list using region id
loc_values = reg_loc[reg_id] if reg_id in reg_loc else []
# Check whether the location is single/multiple
if len(loc_values) > 0 and len(loc_values) == 1:
tracker.slots["site_location"] = loc_values[0]
else:
# Multiple locations select option as bot response
buttons = []
for name in loc_values:
buttons.append({"title": f"{name}", "payload": f"{name}"})
if len(buttons) > 0:
dispatcher.utter_message("Please select the location", buttons=buttons, **tracker.slots)
else:
dispatcher.utter_message("The selected vendor has no locations", **tracker.slots)
return None
return [SlotSet(REQUESTED_SLOT, slot)]
return None
Output: