async def validate_slots(
        self,
        slot_dict: Dict[Text, Any],
        output_channel: "OutputChannel",
        nlg: "NaturalLanguageGenerator",
        tracker: "DialogueStateTracker",
        domain: "Domain",
    ) -> List[Event]:
        events = []
        for slot, value in list(slot_dict.items()):
            validation_rule = self.get_field_for_slot(slot, "validation")
            validated = validate_with_rule(value, validation_rule)

            events += [SlotSet(slot, value if validated else None)]

            # is it changing during this conversational turn? if it did, then:
            # either tracker value is different, or if tracker was updated
            # through regular entity recognition, then this happened in latest event
            # (will not work if multiple entities were extracted in user utterance)
            if tracker.get_slot(slot) != value or (
                    isinstance(tracker.events[-1], SlotSet)
                    and tracker.events[-1].key == slot
                    and tracker.events[-1].value == value):
                events += await self.utter_post_validation(
                    slot, value, validated, output_channel, nlg, tracker,
                    domain)

        return events
Beispiel #2
0
 def check_atomic_condition(self, tracker, field, operator, value, **rest):
     slot = tracker.slots.get(field)
     return validate_with_rule(
         slot.value if slot else None,
         {
             "operator": operator,
             "comparatum": [*value, None
                            ][0]  # value is always a singleton list
         },
     )
    async def validate_slots(
        self,
        slot_dict: Dict[Text, Any],
        output_channel: "OutputChannel",
        nlg: "NaturalLanguageGenerator",
        tracker: "DialogueStateTracker",
        domain: "Domain",
    ) -> List[Event]:
        events = []
        for slot, value in list(slot_dict.items()):
            validation_rule = self.get_field_for_slot(slot, "validation")

            if validation_rule is None:
                events += [SlotSet(slot, value)]
                validated = True
            else:
                operator, comparatum = (
                    validation_rule.get("operator"),
                    validation_rule.get("comparatum"),
                )

                if operator == 'contains' and comparatum == 'custom':
                    validate_name = f"bf_{self.name()}"

                    if validate_name in domain.action_names_or_texts:
                        _tracker = self._temporary_tracker(
                            tracker, events, domain)
                        _action = RemoteAction(validate_name,
                                               self.action_endpoint)
                        validate_events = await _action.run(
                            output_channel, nlg, _tracker, domain)

                        validated_slot_names = [
                            event.key for event in validate_events
                            if isinstance(event, SlotSet)
                        ]

                        if slot not in validated_slot_names:
                            validate_events += [SlotSet(slot, None)]
                        events += validate_events

                        tracker.update_with_events(validate_events, domain)
                        validated = True
                    else:
                        logger.info(f"Action not found: {validate_name}")
                        validated = False
                else:
                    validated = validate_with_rule(value, validation_rule)
                    events += [SlotSet(slot, value if validated else None)]

            # is it changing during this conversational turn? if it did, then:
            # either tracker value is different, or if tracker was updated
            # through regular entity recognition, then this happened in latest event
            # (will not work if multiple entities were extracted in user utterance)
            if tracker.get_slot(slot) != value or (
                    isinstance(tracker.events[-1], SlotSet)
                    and tracker.events[-1].key == slot
                    and tracker.events[-1].value == value):
                events += await self.utter_post_validation(
                    slot, value, validated, output_channel, nlg, tracker,
                    domain)

        return events