Hi Alan,
I will outline a full example below:
Here are a few of my entities and intents, and my form, “count_episode”.
- returnStatus
- number
- timeAbs
- timeAgo
- source
- yearBorn
- zipCode
- time
intents:
- affirm
- deny
- hello
- goodbye
- why
- repeat_please
- skip_please
- inform_countTime
- inform_peopleCount
- inform_vehicleCount
- inform_partyVehics
- inform_returnStatus
- inform_trailVisits
- inform_zipCode
- inform_source
- inform_yearBorn
- inform_howLong
- inform_seenBefore
- inform_seenPastDay
- inform_ambigVehic
- inform_ambigNumber
forms:
- count_episode
Here is my “count_episode” action. The first part is a simple logic that adds more questions depending on prior answers in the form. However, our interest is in the slot map that is defined in slot_mappings():
class ActionCountEpisode(FormAction):
RANDOMIZE = False
@staticmethod
def required_slots(tracker):
base_set = ['seenBefore', "vehicleCount", "countTime", "peopleCount",
"partyVehics", "trailVisits", "source", "returnStatus"]
final_set = base_set
#print("return status: ", tracker.get_slot('returnStatus'))
if tracker.get_slot('returnStatus') == 'return':
final_set += ["howLong"]
if tracker.get_slot('seenBefore') == True:
final_set.insert(1, "seenPastDay")
if tracker.get_slot('seenBefore') == False:
final_set += ["zipCode"]
final_set += ["yearBorn"]
#print(final_set)
return final_set
def name(self):
return 'count_episode'
def slot_mappings(self):
return {"vehicleCount": [self.from_entity(entity="number", intent="inform_vehicleCount"),
self.from_entity(entity="number", intent="inform_ambigVehic"),
self.from_entity(entity="number", intent="inform_ambigNumber")],
"countTime": [self.from_entity(entity="timeAbs", intent="inform_countTime"),
self.from_entity(entity="timeAbs", intent="inform_ambigNumber"),
self.from_entity(entity="timeAgo", intent="inform_countTime"),
self.from_entity(entity="timeAgo", intent="inform_ambigNumber"),
self.from_entity(entity="time", intent="inform_countTime"),
self.from_entity(entity="time", intent="inform_ambigNumber"),
self.from_entity(entity="number", intent="inform_countTime"),
self.from_entity(entity="number", intent="inform_ambigNumber")],
"peopleCount": [self.from_entity(entity="number", intent="inform_peopleCount"),
self.from_entity(entity="number", intent="inform_ambigNumber")],
"partyVehics": [self.from_entity(entity="number", intent="inform_partyVehics"),
self.from_entity(entity="number", intent="inform_ambigVehic"),
self.from_entity(entity="number", intent="inform_ambigNumber")],
"source": self.from_entity(entity="source", intent="inform_source"),
"trailVisits": [self.from_entity(entity="number", intent="inform_trailVisits"),
self.from_entity(entity="number", intent="inform_ambigNumber")],
"returnStatus": self.from_entity(entity="returnStatus", intent="inform_returnStatus"),
"zipCode": self.from_entity(entity="zipCode", intent="inform_zipCode"),
"yearBorn": self.from_entity(entity="yearBorn", intent="inform_yearBorn"),
"seenBefore": [self.from_intent(intent='affirm', value=True),
self.from_intent(intent='deny',value=False)],
"howLong": self.from_entity(entity="timeAgo", intent="inform_howLong"),
"seenPastDay": [self.from_intent(intent='affirm', value=True),
self.from_intent(intent='deny',value=False)]
}
def submit(self, dispatcher, tracker, domain):
return []
My desire is that there might be a switch or parameter that, when a multi-intent is detected, (e.g. inform_countTime+inform_peopleCount), the utterance would search the utterance to fill both potential slots defined in the mapping. However, I don’t want to have to manually code all all combinations of these potential differences. If the intent is returned as inform_countTime+inform_peopleCount
, I want Rasa to do everything it can based on the slot mappings I have already defined for each of these component intents, and update the slots according to the entities it finds in the utterance that would be mapped separately to each of these intents.
The whole idea behind this is in case someone supplies extra information in the form, or perhaps answers the form out of turn, the slots associated with the entities in a particular intent can still be filled, even several in the same utterance. This would reduce duplication in the conversation and increase apparent fluency in the dialogue.