예제 #1
0
        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
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
        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)
예제 #6
0
        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))
예제 #7
0
        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