예제 #1
0
 def collect_slots(slot_dict: Dict[Text, Any]) -> List[Slot]:
     # it is super important to sort the slots here!!!
     # otherwise state ordering is not consistent
     slots = []
     for slot_name in sorted(slot_dict):
         slot_class = Slot.resolve_by_type(slot_dict[slot_name].get("type"))
         if "type" in slot_dict[slot_name]:
             del slot_dict[slot_name]["type"]
         slot = slot_class(slot_name, **slot_dict[slot_name])
         slots.append(slot)
     return slots
예제 #2
0
    async def run(
        self,
        output_channel: "OutputChannel",
        nlg: "NaturalLanguageGenerator",
        tracker: "DialogueStateTracker",
        domain: "Domain",
    ) -> List[Event]:
        # attempt retrieving spec
        if not len(self.form_spec):
            for form in tracker.slots.get(
                    "bf_forms", Slot("bf_forms",
                                     initial_value=[])).initial_value:
                if form.get("name") == self.name():
                    self.form_spec = clean_none_values(form)
            if not len(self.form_spec):
                logger.debug(
                    f"Could not retrieve form '{tracker.active_form}', there is something wrong with your domain."
                )
                return [Form(None)]

        # activate the form
        events = await self._activate_if_required(output_channel, nlg, tracker,
                                                  domain)
        # validate user input
        events.extend(await self._validate_if_required(output_channel, nlg,
                                                       tracker, domain))
        # check that the form wasn't deactivated in validation
        if Form(None) not in events:

            # create temp tracker with populated slots from `validate` method
            temp_tracker = tracker.copy()
            temp_tracker.sender_id = (
                tracker.sender_id)  # copy() doesn't necessarily copy sender_id
            for e in events:
                if isinstance(e, SlotSet):
                    temp_tracker.slots[e.key].value = e.value

            next_slot_events = await self.request_next_slot(
                output_channel, nlg, temp_tracker, domain)

            if next_slot_events is not None:
                # request next slot
                events.extend(next_slot_events)
            else:
                # there is nothing more to request, so we can submit
                self._log_form_slots(temp_tracker)
                logger.debug(f"Submitting the form '{self.name()}'")
                events.extend(await self.submit(output_channel, nlg,
                                                temp_tracker, domain))
                # deactivate the form after submission
                events.extend(self.deactivate())

        return events
예제 #3
0
async def test_parsing_with_tracker():
    tracker = DialogueStateTracker.from_dict("1", [], [Slot("requested_language")])

    # we'll expect this value 'en' to be part of the result from the interpreter
    tracker._set_slot("requested_language", "en")

    endpoint = EndpointConfig("https://interpreter.com")
    with aioresponses() as mocked:
        mocked.post("https://interpreter.com/parse", repeat=True, status=200)

        # mock the parse function with the one defined for this test
        with patch.object(RasaNLUHttpInterpreter, "parse", mocked_parse):
            interpreter = RasaNLUHttpInterpreter(endpoint_config=endpoint)
            agent = Agent(None, None, interpreter)
            result = await agent.parse_message_using_nlu_interpreter("lunch?", tracker)

            assert result["requested_language"] == "en"
예제 #4
0
    def cleaned_domain(self) -> Dict[Text, Any]:
        """Fetch cleaned domain to display or write into a file.

        The internal `used_entities` property is replaced by `use_entities` or
        `ignore_entities` and redundant keys are replaced with default values
        to make the domain easier readable.

        Returns:
            A cleaned dictionary version of the domain.
        """
        domain_data = self.as_dict()

        for idx, intent_info in enumerate(domain_data["intents"]):
            for name, intent in intent_info.items():
                if intent.get(USE_ENTITIES_KEY) is True:
                    del intent[USE_ENTITIES_KEY]
                if not intent.get(IGNORE_ENTITIES_KEY):
                    intent.pop(IGNORE_ENTITIES_KEY, None)
                if len(intent) == 0:
                    domain_data["intents"][idx] = name

        for slot in domain_data["slots"].values():  # pytype: disable=attribute-error
            if slot["initial_value"] is None:
                del slot["initial_value"]
            if slot["auto_fill"]:
                del slot["auto_fill"]
            if slot["type"].startswith("rasa.core.slots"):
                slot["type"] = Slot.resolve_by_type(slot["type"]).type_name

        if domain_data["config"]["store_entities_as_slots"]:
            del domain_data["config"]["store_entities_as_slots"]

        # clean empty keys
        return {
            k: v
            for k, v in domain_data.items()
            if v != {} and v != [] and v is not None
        }
예제 #5
0
 def __missing__(self, key):
     value = self[key] = Slot(key)
     return value
예제 #6
0
 def test_has_a_type_name(self):
     slot = self.create_slot()
     assert slot.type_name is not None
     assert type(slot) == Slot.resolve_by_type(slot.type_name)