Ejemplo n.º 1
0
    def test_converter_args(self):
        """Check converter with arguments."""
        intents = parse_ini("""
        [TestIntent]
        this is a test ten:10!int!pow,3
        """)

        graph = intents_to_graph(intents)
        examples = train(graph)

        def pow_converter(*args, converter_args=None):
            exponent = int(converter_args[0]) if converter_args else 1
            return [x**exponent for x in args]

        # Should convert "ten" -> 10 -> 1000
        recognitions = zero_times(
            recognize(
                "this is a test ten",
                graph,
                examples,
                extra_converters={"pow": pow_converter},
            ))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent", confidence=1),
                    text="this is a test 1000",
                    raw_text="this is a test ten",
                    tokens=["this", "is", "a", "test", 1000],
                    raw_tokens=["this", "is", "a", "test", "ten"],
                )
            ],
        )
Ejemplo n.º 2
0
    def test_optional_entity(self):
        """Ensure entity inside optional is recognized."""
        ini_text = """
        [playBook]
        read me ($audio-book-name){book} in [the] [($assistant-zones){zone}]
        """

        replacements = {
            "$audio-book-name":
            [Sentence.parse("the hound of the baskervilles")],
            "$assistant-zones": [Sentence.parse("bedroom")],
        }

        graph = intents_to_graph(parse_ini(ini_text), replacements)
        examples = train(graph)

        recognitions = zero_times(
            recognize("read me the hound of the baskervilles in the bedroom",
                      graph, examples))
        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertTrue(recognition.intent)

        entities = {e.entity: e for e in recognition.entities}
        self.assertIn("book", entities)
        book = entities["book"]
        self.assertEqual(book.value, "the hound of the baskervilles")

        self.assertIn("zone", entities)
        zone = entities["zone"]
        self.assertEqual(zone.value, "bedroom")
Ejemplo n.º 3
0
    def test_converters(self):
        """Check sentence with converters."""
        intents = parse_ini("""
        [TestIntent]
        this is a test!upper ten:10!int!square
        """)

        graph = intents_to_graph(intents)
        examples = train(graph)

        # Should upper-case "test" and convert "ten" -> 10 -> 100
        recognitions = zero_times(
            recognize(
                "this is a test ten",
                graph,
                examples,
                extra_converters={
                    "square": lambda *args: [x**2 for x in args]
                },
            ))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent", confidence=1),
                    text="this is a TEST 100",
                    raw_text="this is a test ten",
                    tokens=["this", "is", "a", "TEST", 100],
                    raw_tokens=["this", "is", "a", "test", "ten"],
                )
            ],
        )
Ejemplo n.º 4
0
    def test_entity_converters_both(self):
        """Check sentence with an entity converter and a converter inside the entity."""
        intents = parse_ini("""
        [TestIntent]
        this is a test (four:4 point: two:2){number!floatify}
        """)

        graph = intents_to_graph(intents)
        examples = train(graph)

        # "four two" -> 4.2
        recognitions = zero_times(
            recognize(
                "this is a test four point two",
                graph,
                examples,
                extra_converters={
                    "floatify": lambda a, b: [float(f"{a}.{b}")]
                },
            ))

        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertTrue(recognition.intent)

        entities = {e.entity: e for e in recognition.entities}
        self.assertIn("number", entities)
        number = entities["number"]
        self.assertEqual(number.value, 4.2)
Ejemplo n.º 5
0
    def test_rules(self):
        """Make sure local and remote rules work."""
        intents = parse_ini("""
        [Intent1]
        rule = test
        this is a <rule>

        [Intent2]
        rule = this is
        <rule> another <Intent1.rule>
        """)

        graph = intents_to_graph(intents)
        examples = train(graph)

        # Lower confidence with no stop words
        recognitions = zero_times(
            recognize("this is another test", graph, examples))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="Intent2", confidence=1),
                    text="this is another test",
                    raw_text="this is another test",
                    tokens=["this", "is", "another", "test"],
                    raw_tokens=["this", "is", "another", "test"],
                )
            ],
        )
Ejemplo n.º 6
0
    def test_single_sentence(self):
        """Single intent, single sentence."""
        intents = parse_ini("""
        [TestIntent]
        this is a test?
        """)

        graph = intents_to_graph(intents)
        examples = train(graph)

        # Exact
        recognitions = zero_times(recognize("this is a test", graph, examples))

        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent", confidence=1),
                    text="this is a test?",
                    raw_text="this is a test",
                    tokens=["this", "is", "a", "test?"],
                    raw_tokens=["this", "is", "a", "test"],
                )
            ],
        )

        # Mispellings, too many tokens (lower confidence)
        for sentence in ["this is a bad test", "this iz b tst"]:
            recognitions = zero_times(recognize(sentence, graph, examples))
            self.assertEqual(len(recognitions), 1)

            intent = recognitions[0].intent
            self.assertIsNotNone(intent)
            self.assertLess(intent.confidence, 1.0)
Ejemplo n.º 7
0
    def test_intent_filter(self):
        """Identical sentences from two different intents with filter."""
        intents = parse_ini("""
        [TestIntent1]
        this is a test

        [TestIntent2]
        this is a test
        """)

        graph = intents_to_graph(intents)
        examples = train(graph)

        def intent_filter(name):
            return name == "TestIntent1"

        # Should produce a recognition for first intent only
        recognitions = zero_times(
            recognize("this is a test",
                      graph,
                      examples,
                      intent_filter=intent_filter))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent1", confidence=1),
                    text="this is a test",
                    raw_text="this is a test",
                    tokens=["this", "is", "a", "test"],
                    raw_tokens=["this", "is", "a", "test"],
                )
            ],
        )
Ejemplo n.º 8
0
    async def handle_train(
        self, train: NluTrain, site_id: str = "default"
    ) -> typing.AsyncIterable[
        typing.Union[typing.Tuple[NluTrainSuccess, TopicArgs], NluError]
    ]:
        """Transform sentences to intent examples"""
        try:
            _LOGGER.debug("Loading %s", train.graph_path)
            with open(train.graph_path, mode="rb") as graph_file:
                self.intent_graph = rhasspynlu.gzip_pickle_to_graph(graph_file)

            self.examples = rhasspyfuzzywuzzy.train(self.intent_graph)

            if self.examples_path:
                # Write examples to JSON file
                with open(self.examples_path, "w") as examples_file:
                    json.dump(self.examples, examples_file)

                _LOGGER.debug("Wrote %s", str(self.examples_path))

            yield (NluTrainSuccess(id=train.id), {"site_id": site_id})
        except Exception as e:
            _LOGGER.exception("handle_train")
            yield NluError(
                site_id=site_id, session_id=train.id, error=str(e), context=train.id
            )
Ejemplo n.º 9
0
    async def handle_train(
        self,
        train: NluTrain,
        site_id: str = "default"
    ) -> typing.AsyncIterable[typing.Union[typing.Tuple[NluTrainSuccess,
                                                        TopicArgs], NluError]]:
        """Transform sentences to intent examples"""
        try:
            _LOGGER.debug("Loading %s", train.graph_path)
            with open(train.graph_path, mode="rb") as graph_file:
                self.intent_graph = rhasspynlu.gzip_pickle_to_graph(graph_file)

            examples = rhasspyfuzzywuzzy.train(self.intent_graph)

            if self.examples_path:
                if self.examples_path.is_file():
                    # Delete existing file
                    self.examples_path.unlink()

                # Write examples to SQLite database
                conn = sqlite3.connect(str(self.examples_path))
                c = conn.cursor()
                c.execute("""DROP TABLE IF EXISTS intents""")
                c.execute(
                    """CREATE TABLE intents (sentence text, path text)""")

                for _, sentences in examples.items():
                    for sentence, path in sentences.items():
                        c.execute(
                            "INSERT INTO intents VALUES (?, ?)",
                            (sentence, json.dumps(path, ensure_ascii=False)),
                        )

                conn.commit()
                conn.close()

                _LOGGER.debug("Wrote %s", str(self.examples_path))
            yield (NluTrainSuccess(id=train.id), {"site_id": site_id})
        except Exception as e:
            _LOGGER.exception("handle_train")
            yield NluError(site_id=site_id,
                           session_id=train.id,
                           error=str(e),
                           context=train.id)
Ejemplo n.º 10
0
    def setUp(self):
        self.site_id = str(uuid.uuid4())
        self.session_id = str(uuid.uuid4())

        ini_text = """
        [SetLightColor]
        set the (bedroom | living room){name} light to (red | green | blue){color}

        [GetTime]
        what time is it
        """

        self.graph = intents_to_graph(parse_ini(ini_text))
        self.examples = rhasspyfuzzywuzzy.train(self.graph)
        self.client = MagicMock()
        self.hermes = NluHermesMqtt(
            self.client,
            self.graph,
            examples=self.examples,
            confidence_threshold=1.0,
            site_ids=[self.site_id],
        )
Ejemplo n.º 11
0
    def test_entity_converter(self):
        """Check sentence with an entity converter."""
        intents = parse_ini("""
        [TestIntent]
        this is a test (four: point: two:4.2){number!float}
        """)

        graph = intents_to_graph(intents)
        examples = train(graph)

        # "four point two" -> 4.2
        recognitions = zero_times(
            recognize("this is a test four point two", graph, examples))

        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertTrue(recognition.intent)

        entities = {e.entity: e for e in recognition.entities}
        self.assertIn("number", entities)
        number = entities["number"]
        self.assertEqual(number.value, 4.2)
Ejemplo n.º 12
0
    def test_converters_in_entities(self):
        """Check sentence with converters inside an entity."""
        intents = parse_ini("""
        [TestIntent]
        this is a test (ten:10!int){number}
        """)

        graph = intents_to_graph(intents)
        examples = train(graph)

        # ten -> 10 (int)
        recognitions = zero_times(
            recognize("this is a test ten", graph, examples))

        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertTrue(recognition.intent)

        entities = {e.entity: e for e in recognition.entities}
        self.assertIn("number", entities)
        number = entities["number"]
        self.assertEqual(number.value, 10)
Ejemplo n.º 13
0
    def test_sequence_converters(self):
        """Check sentence with sequence converters."""
        intents = parse_ini("""
        [TestIntent]
        this (is a test)!upper
        """)

        graph = intents_to_graph(intents)
        examples = train(graph)

        # Should upper-case "is a test"
        recognitions = zero_times(recognize("this is a test", graph, examples))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent", confidence=1),
                    text="this IS A TEST",
                    raw_text="this is a test",
                    tokens=["this", "IS", "A", "TEST"],
                    raw_tokens=["this", "is", "a", "test"],
                )
            ],
        )