def attempt_intent(self): """ This method attempts to use the slots (variables) descerned so far to execute the intent (functionality). If any slots nescesarry to execute the intent are undefined, the speech packet returned will ask the user for clarifcation. If all the nescesarry slots to execute the intest are defined, the speech packet returned will comunicate the answer. Returns """ ir_name = self.event.request.intent.name if ir_name in self._interrupting_ir_map: ir_handler = self._interrupting_ir_map[ir_name] if ir_handler['terminating']: self.event.session.slots = DotMap({}) speech = ir_handler['function']() elif self._unset_sis: speech = self._unset_sis[0].ask() # just take first one else: self.event.session.slots = DotMap({}) ir_handler = self._ir_map[ir_name]['function'] # we might need to combine slot_interactions with other config # or else define some decent slot_interactions for pure config variables inputs = DotMap({i.slot.name: i.slot.value for i in self.slot_interactions}) speech = ir_handler(inputs) return speech
def stationary_when_intent(self, slots): """ Finds best times for a specific activity in a single lat/lon """ # Get lat, lon from location input place = Nominatim().geocode(slots.location) slots.location = DotMap({ 'lat': place.latitude, 'lon': place.longitude }) # Decode duration slots.totalTime = isodate.parse_duration( slots.totalTime).total_seconds() timesteps = math.ceil(slots.totalTime / float(15 * 60)) start_time = dateutil.parser.parse( slots.startTime).replace(tzinfo=pytz.UTC) whenActionBuilders = [ WhenActionBuilder(slots.score, slots.conditions, slots.location, i * datetime.timedelta(seconds=15 * 60), cache=self._cache) for i in range(int(timesteps)) ] when_filter = [ TimeSlot(start_time, start_time + datetime.timedelta(days=3)) ] a_decision = WhenDecision(whenActionBuilders, when_filter) a_decision.generatePossibleActivities(timeRes=datetime.timedelta( hours=3)) possibilities = a_decision.possibleActivities answers = construct_options_speech(self.event.session.current_intent, possibilities, slots.activity) speech_output = answers[0] self.event.session.custom.remaining_possibilities = answers[1:3] card = make_card(self.event.session.sessionId, self.event.session.user.userId, [p.score.metadata for p in possibilities]) reprompt_text = "" self.event.session.current_intent = "None" return self.say(speech_output, reprompt_text, self.event.request.intent.name, card, False)
def stationary_what_intent(self, slots): """ Finds best activity to do at a given place and time. """ # Get lat, lon from location input place = Nominatim().geocode(slots.location) slots.location = DotMap({ 'lat': place.latitude, 'lon': place.longitude }) # Decode duration slots.totalTime = isodate.parse_duration(slots.totalTime) # Decode time slots.startTime = dateutil.parser.parse( slots.startTime).replace(tzinfo=pytz.UTC) activities = [] for activity in self.all_default_values['StationaryWhenIntent'][ 'default_values']: activities.append( WhatActivity( activity, self.all_default_values['StationaryWhenIntent'] ['general_config'][activity].score, self.all_default_values['StationaryWhenIntent'] ['general_config'][activity].conditions, isodate.parse_duration( self.all_default_values['StationaryWhenIntent'] ['default_values'][activity].totalTime))) timeslot = TimeSlot(slots.startTime, slots.startTime + slots.totalTime) a_decision = WhatDecision(activities, timeslot, slots.location, self._cache) a_decision.generatePossibleActivities( datetime.timedelta(seconds=15 * 60)) possibilities = a_decision.possibleActivities answers = construct_options_speech_what(possibilities) speech_output = answers[0] self.event.session.custom.remaining_possibilities = answers[1:3] self.event.session.current_intent = "None" print self.event.session.custom return self.say(speech_output, speech_output, self.event.request.intent.name, speech_output, False)
def _get_slot_interactions(self): """ Utility function to create a list of slot interactions. returns [SlotInteraction] """ if not self.primary_slot: # load in default slot values from config slot_interactions = [ SlotInteraction(self.event, this_slot, self.speech_config, self.default_values) for this_slot in self.event.session.slots.values() ] return slot_interactions try: pslot = self.event.session.slots[self.primary_slot].value default_values = self.default_values[pslot] general_config = self.general_config[pslot] # load in default slot values from config, or insert questioning SlotInteraction # if not in default values. slot_interactions = [ SlotInteraction(self.event, this_slot, self.speech_config, default_values) for this_slot in self.event.session.slots.values() ] # load in pythnon obejcts from config config_slots = [DotMap({"name": k}) for k in general_config] slot_interactions.extend([ SlotInteraction(self.event, this_slot, self.speech_config, general_config) for this_slot in config_slots ]) except (KeyError, AttributeError): raise PrimarySlotError( self.say( "Sorry, I didn't recognise that " + self.primary_slot, "I didn't recognise that " + self.primary_slot, "Error", "I didn't recognise that " + self.primary_slot)) return slot_interactions
def testCombineSlots2(self): new_slots = DotMap(totalTime=DotMap(name='totalTime'), location=DotMap(name='location'), startTime=DotMap(name='startTime'), activity=DotMap(name='activity', value='run')) stored_slots = DotMap() correctAnswer = new_slots session = Session(self.secondaryInput, "", speech_config, full_conf, self.cache) combined = session._add_new_slots_to_session(new_slots, stored_slots) self.assertEquals(combined, correctAnswer)
def _add_new_slots_to_session(self, nested_new_slots, nested_stored_slots): """ Stores any slots (i.e. variables) recieved from the user in a persistent location in a robust fasion. Note that the dictionaries should of the nested sort (see _unnest_dict). Args: * nested_new_slots (dict): Slots to store * nested_stored_slots (dict): Slots current stored and persisted in this session. Returns: * combined: DotMap """ new_slots = self._unnest_dict(nested_new_slots) stored_slots = self._unnest_dict(nested_stored_slots) stored_slots.update({k: v for k, v in new_slots.items() if v or (k not in stored_slots)}) return DotMap(self._nest_dict(stored_slots))
def __init__(self, event, context, speech_config, default_values, cache): """ Args: * event (dict): User data and metadata * context (dict): Unknown * speech_config (dict): all the different speechlets may be returned * default_values (dict): any default slot values for this user Kwargs: * cache (ForecastCache): Cache object for persisting forecast data between dialogue interactions. Note that this class makes represents dictionary attributes as DotMap object for ease of access. """ self._event = event self._context = context self._cache = cache self.event = DotMap(event) self.context = DotMap(context) self.speech_config = DotMap(speech_config) self.all_default_values = DotMap(default_values) self.primary_slot = None mixin.__init__(self) try: # Copy input from user interaction (`self.event.session.attributes.current_intent`) # into the persisted location (`self.event.session.current_intent`) self.event.session.current_intent = self.event.session.attributes.current_intent except AttributeError: self.event.session.current_intent = "None" try: if self._ir_map[self.event.request.intent.name]['grab_session']: self.event.session.current_intent = self.event.request.intent.name except: pass try: # Load default values from current intent self.default_values = self.all_default_values[self.event.session.current_intent]['default_values'] self.general_config = self.all_default_values[self.event.session.current_intent]['general_config'] self.primary_slot = self._ir_map[self.event.session.current_intent]['primary_slot'] except: self.default_values = self.all_default_values[self.event.request.intent.name]['default_values'] self.general_config = self.all_default_values[self.event.request.intent.name]['general_config'] try: # Are there any stored slots to be retrieved? stored_slots = self.event.session.attributes.slots except AttributeError: stored_slots = DotMap() try: # Did the intent come with any slots? new_slots = self.event.request.intent.slots except AttributeError: new_slots = {} # Now we collect all the slots together. self.event.session.slots = self._add_new_slots_to_session(new_slots, stored_slots) # Load the slot interactions. Give up if given an unknown primary slot. self.slot_interactions = self._get_slot_interactions() self.greeting = self.speech_config.session.greeting self.reprompt = self.speech_config.session.reprompt self.sign_off = self.speech_config.session.sign_off self.help = self.speech_config.session.help