コード例 #1
0
def test_slot_invalid_intent() -> None:
    """
    Here, we will see that an entity will not fill an intent unless the intent has a slot for it.
    `intent_1` doesn't have a slot for an entity of type `entity_2`.
    """
    intent_name = "intent_1"
    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, dest="output.intents")

    # Create a mock `workflow`
    workflow = Workflow([slot_filler])

    # and a mock `Entity`.
    body = "12th december"
    entity = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_1",
        values=[{
            "key": "value"
        }],
    )

    # The RuleBasedSlotFillerPlugin specifies that it expects `Tuple[Intent, List[Entity])` on `access(workflow)`.
    workflow.set("output.intents", [1]).set("output.entities", [entity])

    with pytest.raises(AttributeError):
        workflow.run(Input(utterances=body))
コード例 #2
0
def test_workflow_invalid_set_value():
    """
    We can't set invalid values in workflow.
    """
    workflow = Workflow()
    with pytest.raises(ValueError):
        workflow.set("output.intents", 10)
コード例 #3
0
def test_workflow_invalid_set_path():
    """
    We can't set invalid values in workflow.
    """
    workflow = Workflow()
    with pytest.raises(ValueError):
        workflow.set("invalid.path", [])
コード例 #4
0
def test_slot_filling_multiple() -> None:
    """
    Let's try filling both the slots this time with fill_multiple=True!
    `intent_2` supports both `entity_1` and `entity_2`.
    """
    intent_name = "intent_2"

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules,
                                            dest="output.intents",
                                            fill_multiple=True)

    # Create a mock `workflow`
    workflow = Workflow([slot_filler])

    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # and mock `Entity`-ies.
    body = "12th december"
    entity_1 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_1",
        values=[{
            "key": "value"
        }],
    )

    entity_2 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_2",
        values=[{
            "key": "value"
        }],
    )

    # The RuleBasedSlotFillerPlugin specifies that it expects `Tuple[Intent, List[Entity])` on `access(workflow)`.
    workflow.set("output.intents", [intent]).set("output.entities",
                                                 [entity_1, entity_2])
    _, output = workflow.run(Input(utterances=body))

    # `workflow.output[0]` is the `Intent` we created.
    # The `entity_1_slot` and `entity_2_slot` are filled.
    assert output[const.INTENTS][0]["slots"]["entity_1_slot"]["values"] == [
        entity_1.json()
    ]
    assert output[const.INTENTS][0]["slots"]["entity_2_slot"]["values"] == [
        entity_2.json()
    ]
コード例 #5
0
def test_slot_competition_fill_multiple() -> None:
    """
    What happens when we have two entities of the same type but different value?
    """
    intent_name = "intent_1"

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules,
                                            dest="output.intents",
                                            fill_multiple=True)

    # Create a mock `workflow`
    workflow = Workflow([slot_filler])

    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # Here we have two entities which compete for the same slot but have different values.
    body = "12th december"
    entity_1 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_1",
        values=[{
            "key": "value_1"
        }],
    )

    entity_2 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_1",
        values=[{
            "key": "value_2"
        }],
    )

    workflow.set("output.intents", [intent]).set("output.entities",
                                                 [entity_1, entity_2])
    _, output = workflow.run(Input(utterances=body))

    # `workflow.output[0]` is the `Intent` we created.
    # The `entity_1_slot` and `entity_2_slot` are filled.

    assert output[const.INTENTS][0]["slots"]["entity_1_slot"]["values"] == [
        entity_1.json(),
        entity_2.json(),
    ]
コード例 #6
0
def test_slot_no_fill() -> None:
    """
    Here, we will see that an entity will not fill an intent unless the intent has a slot for it.
    `intent_1` doesn't have a slot for an entity of type `entity_2`.
    """
    intent_name = "intent_1"

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, dest="output.intents")

    # Create a mock `workflow`
    workflow = Workflow([slot_filler])

    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # and a mock `Entity`.
    body = "12th december"
    entity = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_2",
        values=[{
            "key": "value"
        }],
    )

    # The RuleBasedSlotFillerPlugin specifies that it expects `Tuple[Intent, List[Entity])` on `access(workflow)`.
    workflow.set("output.intents", [intent]).set("output.entities", [entity])

    _, output = workflow.run(Input(utterances=body))

    # `workflow.output[0]` is the `Intent` we created.
    # we can see that the `entity_2_slot` is not filled by our mock entity.
    assert "entity_1_slot" not in output[const.INTENTS][0]["slots"]
コード例 #7
0
def test_slot_filling() -> None:
    """
    This test case covers a trivial usage of a slot-filler.
    We have `rules` that demonstrate association of intents with entities and their respective slot-configuration.
    """
    intent_name = "intent_1"

    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, dest="output.intents")

    # Create a mock `workflow`
    workflow = Workflow([slot_filler])

    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # and a mock `Entity`.
    body = "12th december"
    entity = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_1",
        values=[{
            "key": "value"
        }],
    )

    # The RuleBasedSlotFillerPlugin specifies that it expects `Tuple[Intent, List[Entity])` on `access(workflow)`.
    workflow.set("output.intents", [intent]).set("output.entities", [entity])

    _, output = workflow.run(Input(utterances=body))
    intent, *_ = output[const.INTENTS]

    # `workflow.output[0]` is the `Intent` we created.
    # so we are checking if the `entity_1_slot` is filled by our mock entity.
    assert intent["slots"]["entity_1_slot"]["values"][0] == entity.json()
コード例 #8
0
ファイル: plugin.py プロジェクト: Vernacular-ai/dialogy
    def __call__(self, workflow: Workflow) -> None:
        """
        Abstraction for plugin io.

        :param workflow:
        :type workflow: Workflow
        :raises TypeError: If access method is missing, we can't get inputs for transformation.
        """
        logger.enable(str(self)) if self.debug else logger.disable(str(self))

        if workflow.input is None:
            return

        if workflow.output is None:
            return

        if self.prevent(workflow.input, workflow.output):
            return

        value = self.utility(workflow.input, workflow.output)
        if value is not None and isinstance(self.dest, str):
            workflow.set(self.dest, value)