Source code for dialogy.plugins.text.slot_filler.rule_slot_filler

"""
Slot Filling
============

While we describe :ref:`slots <Slot>` in the linked doc. The slot filling is part of an :ref:`intent's<Intent>`
role. This plugin orchestrates the execution of slot filling via methods available on intents.

#. We eagerly apply slot placeholders using the :ref:`apply<ApplySlot>` method. 
#. Once entities are found, we check if the slots can fill them using the :ref:`fill<FillSlot>` method.
#. If no slots were filled, we remove the placeholders using :ref:`cleanup<CleanupSlot>` method.
"""
from typing import List, Union, Set

from dialogy.base import Guard, Input, Output, Plugin
from dialogy.types import BaseEntity
from dialogy.types.intent import Intent
from dialogy.types.slots import Rule


[docs]class RuleBasedSlotFillerPlugin(Plugin): """ A utility :ref:`plugin <AbstractPlugin>` for `slot filling <https://nlpprogress.com/english/intent_detection_slot_filling.html>`._ An :ref:`Intent <intent>` may have a few slots that need to be filled. This plugin can assist filling pertaining to certain intent:entity:slot-name association rules. :ref:`Schema for rules<ApplySlot>` Let's run through a practical example. We will create a workflow and preset the output to have expected intent and entities. .. _RuleBasedSlotFillerPlugin: :param rules: A mapping that defines relationship between an intent, its slots and the entities that fill them. :type rules: Rule :param fill_multiple: More than one item be allowed to fill a single slot. :type fill_multiple: bool :param access: Signature for workflow access is :code:`access(workflow) -> (Intent, List[BaseEntity])` :type access: Optional[PluginFn] :param mutate: Not needed, pass :code:`None`. :type mutate: Optional[PluginFn] Irrespective of the entities that are found, only the listed type in the slot shall be present in `values`. """ def __init__( self, rules: Rule, dest: Union[str, None] = None, guards: Union[List[Guard], None] = None, replace_output: bool = True, fill_multiple: bool = True, debug: bool = False, ) -> None: """ constructor """ # rules # # A `Dict` where each key is an intent name, and each value is another `Dict`, # in which, each key is an entity and value contains the `slot_name` and `entity_type.` # # example: # ``` # rules = {"intent": {"slot_name": "entity_type"}} # ``` super().__init__( dest=dest, guards=guards, debug=debug, replace_output=replace_output ) self.rules: Rule = rules or {} # fill_multiple # A boolean value that commands the slot filler to add multiple values of the # same entity type within a slot. self.fill_multiple = fill_multiple
[docs] def fill(self, intents: List[Intent], entities: List[BaseEntity], expected_slots: Union[Set[str], None] = None) -> List[Intent]: if not intents: return intents intent, *rest = intents intent.apply(self.rules) for entity in entities: intent.fill_slot(entity, fill_multiple=self.fill_multiple, expected_slots=expected_slots) intent.cleanup() return [intent, *rest]
[docs] def utility(self, input_: Input, output: Output) -> List[Intent]: return self.fill(output.intents, output.entities, input_.expected_slots)