Repository: skit-ai/dialogy (language: python)

Issue:
Presence of mutate and reshape in DucklingParser
`_mutate_entity` and `_reshape` methods don't belong in `DucklingParser`. We need them to be implemented via `.from_dict` of individual entities.


Discussion / hints:

Fix patch:
diff --git a/.coveragerc b/.coveragerc
index 2fb48812..76ffab73 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -2,3 +2,4 @@
 omit =
     */cli/project.py
     */cli/__init__.py
+    */parser/**.py
diff --git a/dialogy/parser/text/entity/__init__.py b/dialogy/parser/text/entity/__init__.py
index f59358a5..8b137891 100644
--- a/dialogy/parser/text/entity/__init__.py
+++ b/dialogy/parser/text/entity/__init__.py
@@ -1,1 +1,1 @@
-from dialogy.parser.text.entity.duckling_parser import DucklingParser
+
diff --git a/dialogy/parser/text/entity/duckling_parser.py b/dialogy/parser/text/entity/duckling_parser.py
index f8401092..002e97a2 100644
--- a/dialogy/parser/text/entity/duckling_parser.py
+++ b/dialogy/parser/text/entity/duckling_parser.py
@@ -1,385 +1,6 @@
 """
-.. _duckling_parser:
-
-This module exposes a parser for `Duckling <https://github.com/facebook/duckling>`_.
-
-`Duckling <https://github.com/facebook/duckling>`_ helps parsing values like: :code:`date`, :code:`time`,
-:code:`numbers`, :code:`currency` etc. The parser will expect Duckling to be running as an http service, and provide
-means to connect from the implementation here.
-
-.. code-block:: python
-    :linenos:
-    :emphasize-lines: 4, 30
-
-    from dialogy.workflow import Workflow
-
-    def update_workflow(workflow, entities):
-        workflow.input["duckling_entities"] = entities
-
-    duckling_plugin = DucklingParser(
-        access=lambda workflow: workflow.input["sentence"],
-        # the access method guides the plugin to data within a workflow.
-        # in this case, the `input` property of a workflow is expected
-        # to be a `dict` with a key named "sentence". Check line 30.
-        mutate=update_workflow,
-        # the mutate method guides the plugin to place the processed output
-        # somewhere on the workflow.
-        dimensions=["people"],
-        # Duckling supports multiple dimensions, by specifying a list, we make sure
-        # we are searching for a match within the expected dimensions only.
-        locale="en_IN",
-        # Duckling supports a set of locales, we need to provide this info to
-        # get language specific matches.
-        timezone="Asia/Kolkata",
-        # Date/Time related entities make this field imperative.
-    )() # ⬅️ the instance is also getting called.
-    # Notice that we instantiate the class and also
-    # invoke __call__ method of the instance.
-    # The returned value from the instance is the plugin.
-    #
-    # This is a standard pattern across all plugins.
-
-    workflow = Workflow(preprocessors=[duckling_plugin])
-    workflow.run(input_={"sentence": "there are 7 people"})
-    # Once an input is run through the workflow as on line 30,
-    # we can expect the plugin mutation to create an artifact
-    # as per line 4.
-
+.. deprecated:: DucklingParser will be deprecated, please use DucklingPlugin instead. Please use DucklingPlug
 """
-import json
-from pprint import pformat
-from typing import Any, Callable, Dict, List, Optional
-
-import pytz
-import requests
-from pytz.tzinfo import BaseTzInfo  # type: ignore
-
-from dialogy.constants import EntityKeys
-from dialogy.plugin import Plugin, PluginFn
-from dialogy.types.entity import BaseEntity, dimension_entity_map
-from dialogy.utils.logger import debug_logs, log
-from dialogy.workflow import Workflow
-
-
-class DucklingParser(Plugin):
-    """
-    A :ref:`Plugin<plugin>` for extracting entities using `Duckling <https://github.com/facebook/duckling>`_. Once
-    instantiated, a :code:`duckling_parser` object will interface to an http server, running `Duckling
-    <https://github.com/facebook/duckling>`_.
-
-    This object when used as a plugin, transforms the :code:`List[Dict[str, Any]]` returned from the API to a
-    :ref:`BaseEntity<base_entity>` or one of its subclasses.
-
-    :param dimensions: `Dimensions <https://github.com/facebook/duckling#supported-dimensions>`_. Of the listed
-    dimensions, we support:
-
-        - `Numeral`
-        - `Time`
-        - `TimeInterval`
-        - `Duration`
-        - `People` - This isn't part of the standard, we have a private fork to support this.
-
-        Do note, passing more dimensions is not free. Duckling would search for extra set of patterns just because
-        those dimensions were expected.
-    :type dimensions: Optional[List[str]]
-
-    :param locale: The format for expressing locale requires language code and country name ids. Read about
-        `sections <https://github.com/facebook/duckling#extending-duckling>`_ that define
-        `ISO-639-codes <https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes>`_ for languages and
-        `ISO3166 alpha2 country code <https://www.iso.org/obp/ui/#search/code/>`_ for country codes.
-        Examples: `"en_IN"`, `"en_US"`, `"en_GB"`.
-    :type locale: str
-
-    :param timezone: `pytz` Timezone. This is especially important when services are deployed across different
-    geographies and consistency is expected in the responses. Get a valid value from a `list of tz database timezones
-    <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>`_. Example: `"Asia/Kolkata"` :type timezone:
-    Optional[str]
-
-    :param timeout: There are certain strings which tend to stall Duckling:
-    `example <https://github.com/facebook/duckling/issues/338>`_.
-    In such cases, to prevent the overall experience to slow
-    down as well, provide a certain timeout value, defaults to 0.5.
-    :type timeout: float
-
-    :param url: The address where Duckling's entity parser can be reached, defaults to "http://0.0.0.0:8000/parse".
-    :type url: Optional[str]
-    """
-
-    def __init__(
-        self,
-        dimensions: List[str],
-        locale: str,
-        timezone: str,
-        timeout: float = 0.5,
-        url: str = "http://0.0.0.0:8000/parse",
-        access: Optional[PluginFn] = None,
-        mutate: Optional[PluginFn] = None,
-        debug: bool = False,
-    ) -> None:
-        """
-        constructor
-        """
-        super().__init__(access=access, mutate=mutate, debug=debug)
-        self.dimensions = dimensions
-        self.locale = locale
-        self.timezone = timezone
-        self.timeout = timeout
-        self.url = url
-        self.headers: Dict[str, str] = {
-            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
-        }
-
-    def __set_timezone(self) -> Optional[BaseTzInfo]:
-        """
-        Set timezone as BaseTzInfo from compatible timezone string.
-
-        Raises:
-            pytz.UnknownTimeZoneError:
-
-        :raises pytz.UnknownTimeZoneError: If `self.timezone` is not in `list of tz database
-            timezones <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>`_.
-        :return: A valid timezone
-        :rtype: Optional[BaseTzInfo]
-        """
-        # If timezone is an unsafe string, we will handle a `pytz.UnknownTimeZoneError` exception
-        # and pass a friendly message.
-        try:
-            return pytz.timezone(self.timezone)
-        except pytz.UnknownTimeZoneError as unknown_timezone_error:
-            raise pytz.UnknownTimeZoneError(
-                f"The timezone {self.timezone} is invalid"
-                " check valid types here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones"
-            ) from unknown_timezone_error
-
-    @debug_logs
-    def __create_req_body(
-        self, text: str, reference_time: Optional[int]
-    ) -> Dict[str, Any]:
-        """
-        create request body for entity parsing
-
-        example: "3 people tomorrow"
-
-        Make your own reference time using the current timestamp using: :code:`int(datetime.now().timestamp() * 1000)`
-        These are the seconds since the `Unix epoch <https://en.wikipedia.org/wiki/Unix_time>`_
-
-        :param text: A sentence or document.
-        :type text: str
-        :param reference_time: Impart context of timestamp,
-        relevant for time related entities. Resolve relative time like "yesterday", "next month", etc.
-        :type Optional[int]
-        :param reference_time: Optional[int]
-        :return: request object for Duckling API.
-        :rtype: Dict[str, Any]
-        """
-        dimensions = self.dimensions
-
-        payload = {
-            "text": text,
-            "locale": self.locale,
-            "tz": self.__set_timezone(),
-            "dims": json.dumps(dimensions),
-            "reftime": reference_time,
-        }
-        log.debug("Duckling API payload:")
-        log.debug(pformat(payload))
-
-        return payload
-
-    @staticmethod
-    def _mutate_entity(entity: Dict[str, Any]) -> Dict[str, Any]:
-        """
-        Mutate entity obtained from Duckling API.
-
-        The purpose is to simplify :ref:`BaseEntity <base_entity>` initialization by calling `BaseEntity.from_dict(
-        **entity)`.
-
-        :param entity: An entity returned from Duckling's API.
-        :type entity: Dict[str, Any]
-        :return: Updated keys and structure.
-        :rtype: Dict[str, Any]
-        """
-
-        # **range** describes the span of string from which the entity was found.
-
-        match_start = entity[EntityKeys.START]
-        match_end = entity[EntityKeys.END]
-
-        entity[EntityKeys.RANGE] = {
-            EntityKeys.START: match_start,
-            EntityKeys.END: match_end,
-        }
-
-        # **type** of an entity is same as its **dimension**.
-        entity[EntityKeys.TYPE] = entity[EntityKeys.DIM]
-
-        # This piece is a preparation for multiple entity values.
-        # So, even though we are confident of the value found, we are still keeping the
-        # structure.
-        if EntityKeys.VALUES in entity[EntityKeys.VALUE]:
-            del entity[EntityKeys.VALUE][EntityKeys.VALUES]
-        entity[EntityKeys.VALUES] = [entity[EntityKeys.VALUE]]
-
-        # Pulling out the value of entity's **grain**. The value of **grain** helps
-        # us understand the precision of the entity. Usually present for `Time` dimension
-        # expect "year", "month", "day", etc.
-        if EntityKeys.GRAIN in entity[EntityKeys.VALUE]:
-            entity[EntityKeys.GRAIN] = entity[EntityKeys.VALUE][EntityKeys.GRAIN]
-        elif entity[EntityKeys.VALUE][EntityKeys.TYPE] == EntityKeys.INTERVAL:
-            date_range = entity[EntityKeys.VALUE].get(EntityKeys.FROM) or entity[
-                EntityKeys.VALUE
-            ].get(EntityKeys.TO)
-            if not date_range:
-                raise TypeError(f"{entity} does not match TimeIntervalEntity format")
-            entity[EntityKeys.GRAIN] = date_range[EntityKeys.GRAIN]
-
-        del entity[EntityKeys.START]
-        del entity[EntityKeys.END]
-        del entity[EntityKeys.VALUE]
-        return entity
-
-    def _reshape(
-        self, entities_json: List[Dict[str, Any]]
-    ) -> Optional[List[BaseEntity]]:
-        """
-        Create a list of :ref:`BaseEntity <base_entity>` objects from a list of entity dicts.
-
-        :param entities_json: List of entities derived from Duckling's API.
-        :type entities_json: List[Dict[str, Any]]
-        :raises NotImplementedError: Raised when dimensions not supported by the project are used.
-        :raises KeyError: Expected keys in entity dict don't match the Entity class.
-        :return: A list of objects subclassed from :ref:`BaseEntity <base_entity>`
-        :rtype: Optional[List[BaseEntity]]
-        """
-        entity_object_list: List[BaseEntity] = []
-
-        try:
-            # For each entity dict:
-            for entity in entities_json:
-                if entity[EntityKeys.VALUE][EntityKeys.TYPE] in [
-                    EntityKeys.VALUE,
-                    EntityKeys.DURATION,
-                    EntityKeys.INTERVAL,
-                ]:
-                    # We can auto convert dict forms of duckling entities to dialogy entity classes only if they are
-                    # known in advance. We currently support only the types in the condition above.
-                    if entity[EntityKeys.VALUE][EntityKeys.TYPE] == EntityKeys.INTERVAL:
-                        # Duckling entities with interval type have a different structure for value(s).
-                        # They have a need to express units in "from", "to" format.
-                        cls = dimension_entity_map[entity[EntityKeys.DIM]][EntityKeys.INTERVAL]  # type: ignore
-                    else:
-                        cls = dimension_entity_map[entity[EntityKeys.DIM]][EntityKeys.VALUE]  # type: ignore
-                    # The most appropriate class is picked for making an object from the dict.
-                    duckling_entity = cls.from_dict(self._mutate_entity(entity))
-                    # Depending on the type of entity, the value is searched and filled.
-                    duckling_entity.set_value()
-                    # Collect the entity object in a list.
-                    entity_object_list.append(duckling_entity)
-                else:
-                    # Raised only if an unsupported `dimension` is used.
-                    raise NotImplementedError(
-                        f"Entities with value.type {entity['value']['type']} are"
-                        " not implemented. Report this"
-                        " issue here: https://github.com/Vernacular-ai/dialogy/issues"
-                    )
-        except KeyError as key_error:
-            # Being vary of structural changes in the API or entity dicts.
-            # Under normal circumstances this error shouldn't be raised.
-            raise KeyError(
-                f"Missing key {key_error} in entity {entity}."
-            ) from key_error
-        return entity_object_list
-
-    def _get_entities(
-        self, text: str, reference_time: Optional[int] = None
-    ) -> List[Dict[str, Any]]:
-        """
-        Get entities from duckling-server.
-
-        Assuming duckling-server is running at expected `url`. The entities are returned in
-        `json` compatible format.
-
-        :param text: The sentence or document in which entities must be looked up.
-        :type text: str
-        :param reference_time: Cases where relative units of time are mentioned,
-                                like "today", "now", etc. We need to know the current time
-                                to parse the values into usable dates/times, defaults to None
-        :type reference_time: Optional[int], optional
-        :raises ValueError: Duckling API call failure leading to no json response.
-        :return: Duckling entities as python :code:`dicts`.
-        :rtype: List[Dict[str, Any]]
-        """
-        body = self.__create_req_body(text, reference_time)
-        response = requests.post(
-            self.url, data=body, headers=self.headers, timeout=self.timeout
-        )
-
-        if response.status_code == 200:
-            # The API call was successful, expect the following to contain entities.
-            # A list of dicts or an empty list.
-            return response.json()
-
-        # Control flow reaching here would mean the API call wasn't successful.
-        # To prevent rest of the things from crashing, we will raise an exception.
-        raise ValueError(
-            f"Duckling API call failed | [{response.status_code}]: {response.text}"
-        )
-
-    def plugin(self, workflow: Workflow) -> None:
-        """
-        Insert a list of :ref:`BaseEntity <base_entity>` objects into the Workflow.
-
-        This function is also available through the __call__ method as syntactic sugar.
-
-        :param workflow: A :ref:`Workflow <workflow>` on which the plugin should operate.
-        :return:
-        """
-        access = self.access
-        mutate = self.mutate
-        if not isinstance(access, Callable):  # type: ignore
-            raise TypeError(
-                "Expected `access` to be Callable,"
-                f" got access={type(access)} mutate={type(mutate)}"
-            )
-        if not isinstance(mutate, Callable):  # type: ignore
-            raise TypeError(
-                "Expected `mutate` to be Callable,"
-                f" got access={type(access)} mutate={type(mutate)}"
-            )
-
-        entities = []
-        if access and mutate:
-            input_, reference_time = access(workflow)
-            try:
-                if isinstance(input_, str):
-                    entities.append(
-                        self._get_entities(input_, reference_time=reference_time)
-                    )
-                elif isinstance(input_, list) and all(
-                    isinstance(text, str) for text in input_
-                ):
-                    for text in input_:
-                        entities.append(
-                            self._get_entities(text, reference_time=reference_time)
-                        )
-                else:
-                    raise TypeError(f"Expected {input_} to be a List[str] or str.")
-
-                entities_flattened = [
-                    entity for entity_list in entities for entity in entity_list
-                ]
-
-                if entities_flattened:
-                    shaped_entities = self._reshape(entities_flattened)
-                    mutate(workflow, shaped_entities)
-                else:
-                    mutate(workflow, [])
-            except ValueError as value_error:
-                raise ValueError(str(value_error)) from value_error
+from dialogy.preprocess.text.duckling_plugin import DucklingPlugin
 
-    # == __call__ ==
-    def __call__(self) -> PluginFn:
-        """
-        Syntactical sugar.
-        """
-        return self.plugin
+DucklingParser = DucklingPlugin
diff --git a/dialogy/plugin/plugin.py b/dialogy/plugin/plugin.py
index f1874095..b96f8a5f 100644
--- a/dialogy/plugin/plugin.py
+++ b/dialogy/plugin/plugin.py
@@ -69,7 +69,7 @@ def load_corpus(corpus_dir: str, file_path: str) -> None:
 
     We ship a few :ref:`Plugins <plugin>` with Dialogy, namely:
 
-    1. :ref:`DucklingParser <duckling_parser>` (pre-processing)
+    1. :ref:`DucklingPlugin <duckling_plugin>` (pre-processing)
     2. :ref:`merge_asr_output_plugin <merge_asr_output_plugin>` (pre-processing)
     3. :ref:`RuleBasedSlotFillerPlugin <rule_slot_filler>` (post-processing)
     4. :ref:`VotePlugin <vote_plugin>` (post-processing)
diff --git a/dialogy/preprocess/text/duckling_plugin.py b/dialogy/preprocess/text/duckling_plugin.py
new file mode 100644
index 00000000..388255d3
--- /dev/null
+++ b/dialogy/preprocess/text/duckling_plugin.py
@@ -0,0 +1,333 @@
+"""
+.. _duckling_parser:
+
+This module exposes a parser for `Duckling <https://github.com/facebook/duckling>`_.
+
+`Duckling <https://github.com/facebook/duckling>`_ helps parsing values like: :code:`date`, :code:`time`,
+:code:`numbers`, :code:`currency` etc. The parser will expect Duckling to be running as an http service, and provide
+means to connect from the implementation here.
+
+.. code-block:: python
+    :linenos:
+    :emphasize-lines: 4, 30
+
+    from dialogy.workflow import Workflow
+
+    def update_workflow(workflow, entities):
+        workflow.input["duckling_entities"] = entities
+
+    duckling_plugin = DucklingPlugin(
+        access=lambda workflow: workflow.input["sentence"],
+        # the access method guides the plugin to data within a workflow.
+        # in this case, the `input` property of a workflow is expected
+        # to be a `dict` with a key named "sentence". Check line 30.
+        mutate=update_workflow,
+        # the mutate method guides the plugin to place the processed output
+        # somewhere on the workflow.
+        dimensions=["people"],
+        # Duckling supports multiple dimensions, by specifying a list, we make sure
+        # we are searching for a match within the expected dimensions only.
+        locale="en_IN",
+        # Duckling supports a set of locales, we need to provide this info to
+        # get language specific matches.
+        timezone="Asia/Kolkata",
+        # Date/Time related entities make this field imperative.
+    )() # ⬅️ the instance is also getting called.
+    # Notice that we instantiate the class and also
+    # invoke __call__ method of the instance.
+    # The returned value from the instance is the plugin.
+    #
+    # This is a standard pattern across all plugins.
+
+    workflow = Workflow(preprocessors=[duckling_plugin])
+    workflow.run(input_={"sentence": "there are 7 people"})
+    # Once an input is run through the workflow as on line 30,
+    # we can expect the plugin mutation to create an artifact
+    # as per line 4.
+
+"""
+import json
+from pprint import pformat
+from typing import Any, Callable, Dict, List, Optional
+
+import pytz
+import requests
+from pytz.tzinfo import BaseTzInfo  # type: ignore
+
+from dialogy.constants import EntityKeys
+from dialogy.plugin import Plugin, PluginFn
+from dialogy.types.entity import BaseEntity, dimension_entity_map
+from dialogy.utils.logger import debug_logs, log
+from dialogy.workflow import Workflow
+
+
+class DucklingPlugin(Plugin):
+    """
+    A :ref:`Plugin<plugin>` for extracting entities using `Duckling <https://github.com/facebook/duckling>`_. Once
+    instantiated, a :code:`duckling_parser` object will interface to an http server, running `Duckling
+    <https://github.com/facebook/duckling>`_.
+
+    This object when used as a plugin, transforms the :code:`List[Dict[str, Any]]` returned from the API to a
+    :ref:`BaseEntity<base_entity>` or one of its subclasses.
+
+    :param dimensions: `Dimensions <https://github.com/facebook/duckling#supported-dimensions>`_. Of the listed
+    dimensions, we support:
+
+        - `Numeral`
+        - `Time`
+        - `TimeInterval`
+        - `Duration`
+        - `People` - This isn't part of the standard, we have a private fork to support this.
+
+        Do note, passing more dimensions is not free. Duckling would search for extra set of patterns just because
+        those dimensions were expected.
+    :type dimensions: Optional[List[str]]
+
+    :param locale: The format for expressing locale requires language code and country name ids. Read about
+        `sections <https://github.com/facebook/duckling#extending-duckling>`_ that define
+        `ISO-639-codes <https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes>`_ for languages and
+        `ISO3166 alpha2 country code <https://www.iso.org/obp/ui/#search/code/>`_ for country codes.
+        Examples: `"en_IN"`, `"en_US"`, `"en_GB"`.
+    :type locale: str
+
+    :param timezone: `pytz` Timezone. This is especially important when services are deployed across different
+    geographies and consistency is expected in the responses. Get a valid value from a `list of tz database timezones
+    <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>`_. Example: `"Asia/Kolkata"` :type timezone:
+    Optional[str]
+
+    :param timeout: There are certain strings which tend to stall Duckling:
+    `example <https://github.com/facebook/duckling/issues/338>`_.
+    In such cases, to prevent the overall experience to slow
+    down as well, provide a certain timeout value, defaults to 0.5.
+    :type timeout: float
+
+    :param url: The address where Duckling's entity parser can be reached, defaults to "http://0.0.0.0:8000/parse".
+    :type url: Optional[str]
+    """
+
+    def __init__(
+        self,
+        dimensions: List[str],
+        locale: str,
+        timezone: str,
+        timeout: float = 0.5,
+        url: str = "http://0.0.0.0:8000/parse",
+        access: Optional[PluginFn] = None,
+        mutate: Optional[PluginFn] = None,
+        debug: bool = False,
+    ) -> None:
+        """
+        constructor
+        """
+        super().__init__(access=access, mutate=mutate, debug=debug)
+        self.dimensions = dimensions
+        self.locale = locale
+        self.timezone = timezone
+        self.timeout = timeout
+        self.url = url
+        self.headers: Dict[str, str] = {
+            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
+        }
+
+    def __set_timezone(self) -> Optional[BaseTzInfo]:
+        """
+        Set timezone as BaseTzInfo from compatible timezone string.
+
+        Raises:
+            pytz.UnknownTimeZoneError:
+
+        :raises pytz.UnknownTimeZoneError: If `self.timezone` is not in `list of tz database
+            timezones <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>`_.
+        :return: A valid timezone
+        :rtype: Optional[BaseTzInfo]
+        """
+        # If timezone is an unsafe string, we will handle a `pytz.UnknownTimeZoneError` exception
+        # and pass a friendly message.
+        try:
+            return pytz.timezone(self.timezone)
+        except pytz.UnknownTimeZoneError as unknown_timezone_error:
+            raise pytz.UnknownTimeZoneError(
+                f"The timezone {self.timezone} is invalid"
+                " check valid types here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones"
+            ) from unknown_timezone_error
+
+    @debug_logs
+    def __create_req_body(
+        self, text: str, reference_time: Optional[int]
+    ) -> Dict[str, Any]:
+        """
+        create request body for entity parsing
+
+        example: "3 people tomorrow"
+
+        Make your own reference time using the current timestamp using: :code:`int(datetime.now().timestamp() * 1000)`
+        These are the seconds since the `Unix epoch <https://en.wikipedia.org/wiki/Unix_time>`_
+
+        :param text: A sentence or document.
+        :type text: str
+        :param reference_time: Impart context of timestamp,
+        relevant for time related entities. Resolve relative time like "yesterday", "next month", etc.
+        :type Optional[int]
+        :param reference_time: Optional[int]
+        :return: request object for Duckling API.
+        :rtype: Dict[str, Any]
+        """
+        dimensions = self.dimensions
+
+        payload = {
+            "text": text,
+            "locale": self.locale,
+            "tz": self.__set_timezone(),
+            "dims": json.dumps(dimensions),
+            "reftime": reference_time,
+        }
+        log.debug("Duckling API payload:")
+        log.debug(pformat(payload))
+
+        return payload
+
+    def _reshape(
+        self, entities_json: List[Dict[str, Any]]
+    ) -> Optional[List[BaseEntity]]:
+        """
+        Create a list of :ref:`BaseEntity <base_entity>` objects from a list of entity dicts.
+
+        :param entities_json: List of entities derived from Duckling's API.
+        :type entities_json: List[Dict[str, Any]]
+        :raises NotImplementedError: Raised when dimensions not supported by the project are used.
+        :raises KeyError: Expected keys in entity dict don't match the Entity class.
+        :return: A list of objects subclassed from :ref:`BaseEntity <base_entity>`
+        :rtype: Optional[List[BaseEntity]]
+        """
+        entity_object_list: List[BaseEntity] = []
+
+        try:
+            # For each entity dict:
+            for entity in entities_json:
+                if entity[EntityKeys.VALUE][EntityKeys.TYPE] in [
+                    EntityKeys.VALUE,
+                    EntityKeys.DURATION,
+                    EntityKeys.INTERVAL,
+                ]:
+                    # We can auto convert dict forms of duckling entities to dialogy entity classes only if they are
+                    # known in advance. We currently support only the types in the condition above.
+                    if entity[EntityKeys.VALUE][EntityKeys.TYPE] == EntityKeys.INTERVAL:
+                        # Duckling entities with interval type have a different structure for value(s).
+                        # They have a need to express units in "from", "to" format.
+                        cls = dimension_entity_map[entity[EntityKeys.DIM]][EntityKeys.INTERVAL]  # type: ignore
+                    else:
+                        cls = dimension_entity_map[entity[EntityKeys.DIM]][EntityKeys.VALUE]  # type: ignore
+                    # The most appropriate class is picked for making an object from the dict.
+                    duckling_entity = cls.from_dict(entity)
+                    # Depending on the type of entity, the value is searched and filled.
+                    duckling_entity.set_value()
+                    # Collect the entity object in a list.
+                    entity_object_list.append(duckling_entity)
+                else:
+                    # Raised only if an unsupported `dimension` is used.
+                    raise NotImplementedError(
+                        f"Entities with value.type {entity['value']['type']} are"
+                        " not implemented. Report this"
+                        " issue here: https://github.com/Vernacular-ai/dialogy/issues"
+                    )
+        except KeyError as key_error:
+            # Being vary of structural changes in the API or entity dicts.
+            # Under normal circumstances this error shouldn't be raised.
+            raise KeyError(
+                f"Missing key {key_error} in entity {entity}."
+            ) from key_error
+        return entity_object_list
+
+    def _get_entities(
+        self, text: str, reference_time: Optional[int] = None
+    ) -> List[Dict[str, Any]]:
+        """
+        Get entities from duckling-server.
+
+        Assuming duckling-server is running at expected `url`. The entities are returned in
+        `json` compatible format.
+
+        :param text: The sentence or document in which entities must be looked up.
+        :type text: str
+        :param reference_time: Cases where relative units of time are mentioned,
+                                like "today", "now", etc. We need to know the current time
+                                to parse the values into usable dates/times, defaults to None
+        :type reference_time: Optional[int], optional
+        :raises ValueError: Duckling API call failure leading to no json response.
+        :return: Duckling entities as python :code:`dicts`.
+        :rtype: List[Dict[str, Any]]
+        """
+        body = self.__create_req_body(text, reference_time)
+        response = requests.post(
+            self.url, data=body, headers=self.headers, timeout=self.timeout
+        )
+
+        if response.status_code == 200:
+            # The API call was successful, expect the following to contain entities.
+            # A list of dicts or an empty list.
+            return response.json()
+
+        # Control flow reaching here would mean the API call wasn't successful.
+        # To prevent rest of the things from crashing, we will raise an exception.
+        raise ValueError(
+            f"Duckling API call failed | [{response.status_code}]: {response.text}"
+        )
+
+    def plugin(self, workflow: Workflow) -> None:
+        """
+        Insert a list of :ref:`BaseEntity <base_entity>` objects into the Workflow.
+
+        This function is also available through the __call__ method as syntactic sugar.
+
+        :param workflow: A :ref:`Workflow <workflow>` on which the plugin should operate.
+        :return:
+        """
+        access = self.access
+        mutate = self.mutate
+        if not isinstance(access, Callable):  # type: ignore
+            raise TypeError(
+                "Expected `access` to be Callable,"
+                f" got access={type(access)} mutate={type(mutate)}"
+            )
+        if not isinstance(mutate, Callable):  # type: ignore
+            raise TypeError(
+                "Expected `mutate` to be Callable,"
+                f" got access={type(access)} mutate={type(mutate)}"
+            )
+
+        entities = []
+        if access and mutate:
+            input_, reference_time = access(workflow)
+            try:
+                if isinstance(input_, str):
+                    entities.append(
+                        self._get_entities(input_, reference_time=reference_time)
+                    )
+                elif isinstance(input_, list) and all(
+                    isinstance(text, str) for text in input_
+                ):
+                    for text in input_:
+                        entities.append(
+                            self._get_entities(text, reference_time=reference_time)
+                        )
+                else:
+                    raise TypeError(f"Expected {input_} to be a List[str] or str.")
+
+                entities_flattened = [
+                    entity for entity_list in entities for entity in entity_list
+                ]
+
+                if entities_flattened:
+                    shaped_entities = self._reshape(entities_flattened)
+                    mutate(workflow, shaped_entities)
+                else:
+                    mutate(workflow, [])
+            except ValueError as value_error:
+                raise ValueError(str(value_error)) from value_error
+
+    # == __call__ ==
+    def __call__(self) -> PluginFn:
+        """
+        Syntactical sugar.
+        """
+        return self.plugin
diff --git a/dialogy/preprocess/text/normalize_utterance.py b/dialogy/preprocess/text/normalize_utterance.py
index 11542f95..d2d7af5c 100644
--- a/dialogy/preprocess/text/normalize_utterance.py
+++ b/dialogy/preprocess/text/normalize_utterance.py
@@ -26,11 +26,11 @@ def dict_get(prop: str, obj: Dict[str, Any]) -> Any:
 
 def is_list(input_: Any) -> bool:
     """
-    Check type of `input_`
+    Check type of :code:`input`
 
     :param input_: Any arbitrary input
     :type input_: Any
-    :return: True if input_ is a :code:`list` else False
+    :return: True if :code:`input` is a :code:`list` else False
     :rtype: True
     """
     return isinstance(input_, list)
@@ -68,11 +68,14 @@ def is_each_element(
 def is_utterance(maybe_utterance: Any, key: str = const.TRANSCRIPT) -> bool:
     """
     .. _is_utterance:
+
     Check input to be of `List[List[Dict]]`.
 
-    ```json
-    [[{"transcript": "hi"}]]
-    ```
+
+    .. code-blocks: json
+
+        [[{"transcript": "hi"}]]
+
 
     .. ipython:: python
 
diff --git a/dialogy/types/entity/base_entity.py b/dialogy/types/entity/base_entity.py
index a028c6b8..928d0614 100644
--- a/dialogy/types/entity/base_entity.py
+++ b/dialogy/types/entity/base_entity.py
@@ -118,6 +118,35 @@ def validate(cls, dict_: Dict[str, Any]) -> None:
         for prop, prop_type in cls.__properties_map:
             validate_type(traverse_dict(dict_, prop), prop_type)
 
+    @classmethod
+    def reshape(cls, dict_: Dict[str, Any]) -> Dict[str, Any]:
+        """
+        :type dict_: Dict[str, Any]
+        """
+        match_start = dict_[const.EntityKeys.START]
+        match_end = dict_[const.EntityKeys.END]
+
+        dict_[const.EntityKeys.RANGE] = {
+            const.EntityKeys.START: match_start,
+            const.EntityKeys.END: match_end,
+        }
+        # ['body', 'start', 'value', 'end', 'dim', 'latent']
+
+        # **type** of an entity is same as its **dimension**.
+        dict_[const.EntityKeys.TYPE] = dict_[const.EntityKeys.DIM]
+
+        # This piece is a preparation for multiple entity values.
+        # So, even though we are confident of the value found, we are still keeping the
+        # structure.
+        if const.EntityKeys.VALUES in dict_[const.EntityKeys.VALUE]:
+            del dict_[const.EntityKeys.VALUE][const.EntityKeys.VALUES]
+        dict_[const.EntityKeys.VALUES] = [dict_[const.EntityKeys.VALUE]]
+
+        del dict_[const.EntityKeys.START]
+        del dict_[const.EntityKeys.END]
+        del dict_[const.EntityKeys.VALUE]
+        return dict_
+
     @classmethod
     def from_dict(cls, dict_: Dict[str, Any]) -> "BaseEntity":
         """
@@ -131,6 +160,7 @@ def from_dict(cls, dict_: Dict[str, Any]) -> "BaseEntity":
         :return: Instance of class
         :rtype: BaseEntity
         """
+        dict_ = cls.reshape(dict_)
         cls.validate(dict_)
         return cls(**dict_)
 
diff --git a/dialogy/types/entity/time_entity.py b/dialogy/types/entity/time_entity.py
index 630065be..c386a7fe 100644
--- a/dialogy/types/entity/time_entity.py
+++ b/dialogy/types/entity/time_entity.py
@@ -5,11 +5,11 @@
 Import classes:
     - TimeEntity
 """
-from typing import Optional
+from typing import Any, Dict, Optional
 
 import attr
 
-from dialogy import constants
+from dialogy import constants as const
 from dialogy.types.entity.numerical_entity import NumericalEntity
 
 
@@ -29,7 +29,21 @@ class TimeEntity(NumericalEntity):
 
     dim = "time"
     grain = attr.ib(type=str, default=None, validator=attr.validators.instance_of(str))
-    __properties_map = constants.TIME_ENTITY_PROPS
+    __properties_map = const.TIME_ENTITY_PROPS
+
+    @classmethod
+    def reshape(cls, dict_: Dict[str, Any]) -> Dict[str, Any]:
+        dict_ = super(TimeEntity, cls).reshape(dict_)
+        # Pulling out the value of entity's **grain**. The value of **grain** helps
+        # us understand the precision of the entity. Usually present for `Time` dimension
+        # expect "year", "month", "day", etc.
+        if all(
+            const.EntityKeys.GRAIN in value for value in dict_[const.EntityKeys.VALUES]
+        ):
+            dict_[const.EntityKeys.GRAIN] = dict_[const.EntityKeys.VALUES][0][
+                const.EntityKeys.GRAIN
+            ]
+        return dict_
 
     def __attrs_post_init__(self) -> None:
         grain_: Optional[str] = None
diff --git a/dialogy/types/entity/time_interval_entity.py b/dialogy/types/entity/time_interval_entity.py
index 888abc42..d2da49a5 100644
--- a/dialogy/types/entity/time_interval_entity.py
+++ b/dialogy/types/entity/time_interval_entity.py
@@ -30,6 +30,21 @@ class TimeIntervalEntity(TimeEntity):
     dim = "time"
     __properties_map = const.TIME_ENTITY_PROPS
 
+    @classmethod
+    def reshape(cls, dict_: Dict[str, Any]) -> Dict[str, Any]:
+        dict_ = super(TimeIntervalEntity, cls).reshape(dict_)
+        if all(
+            value[const.EntityKeys.TYPE] == const.EntityKeys.INTERVAL
+            for value in dict_[const.EntityKeys.VALUES]
+        ):
+            date_range = dict_[const.EntityKeys.VALUES][0].get(
+                const.EntityKeys.FROM
+            ) or dict_[const.EntityKeys.VALUES][0].get(const.EntityKeys.TO)
+            if not date_range:
+                raise TypeError(f"{dict_} does not match TimeIntervalEntity format")
+            dict_[const.EntityKeys.GRAIN] = date_range[const.EntityKeys.GRAIN]
+        return dict_
+
     def set_value(self, value: Optional[Dict[str, Any]] = None) -> None:
         """
         Set values and value attribute.
diff --git a/dialogy/workflow/workflow.py b/dialogy/workflow/workflow.py
index 44fcaf96..9f945870 100644
--- a/dialogy/workflow/workflow.py
+++ b/dialogy/workflow/workflow.py
@@ -12,7 +12,7 @@
 `anything`? through it, it would pass through with a thud on the ground `(yes we assumed gravity)`.
 
 All good but that's not special? Why would anyone need that?
-----
+-------------------------------------------------------------
 
 A workflow allows flexibility, that's why. There is very little structure to it. We have:
 
@@ -26,7 +26,7 @@
 your :ref:`Workflow <Workflow>` won't judge you.
 
 Where's the sauce?
-----
+-------------------
 
 The :ref:`Plugin<plugin>` concept takes care of the sauciness 🍅 of this project. Any functionality can be bundled into
 a :ref:`Plugin<plugin>` and they are portable over to foreign workflows. A :ref:`Plugin<plugin>` proxies inputs through
@@ -34,7 +34,7 @@
 function (another argument for every :ref:`Plugin<plugin>`). These two functions define interactions between many many
 (sic) :ref:`Plugins<plugin>` without knowing the inner workings of a :ref:`Workflow <workflow>`.
 
-Take a look at :ref:`DucklingParser <Duckling>`, this plugin handles inputs, manages the default :code:`json` output
+Take a look at :ref:`DucklingPlugin <duckling_plugin>`, this plugin handles inputs, manages the default :code:`json` output
 into neatly bundled :ref:`BaseEntity <base_entity>` and other similar classes. Another plugin
 :ref:`RuleBasedSlotFillerPlugin<rule_slot_filler>` takes care of slot names and the entity types that should be filled
 within.
diff --git a/docs/_modules/dialogy/plugin/plugin.html b/docs/_modules/dialogy/plugin/plugin.html
index 92f6a2ec..0c2d96de 100644
--- a/docs/_modules/dialogy/plugin/plugin.html
+++ b/docs/_modules/dialogy/plugin/plugin.html
@@ -235,7 +235,7 @@ <h1>Source code for dialogy.plugin.plugin</h1><div class="highlight"><pre>
 
     We ship a few :ref:`Plugins &lt;plugin&gt;` with Dialogy, namely:
 
-    1. :ref:`DucklingParser &lt;duckling_parser&gt;` (pre-processing)
+    1. :ref:`DucklingPlugin &lt;duckling_plugin&gt;` (pre-processing)
     2. :ref:`merge_asr_output_plugin &lt;merge_asr_output_plugin&gt;` (pre-processing)
     3. :ref:`RuleBasedSlotFillerPlugin &lt;rule_slot_filler&gt;` (post-processing)
     4. :ref:`VotePlugin &lt;vote_plugin&gt;` (post-processing)
diff --git a/docs/_modules/dialogy/preprocess/text/normalize_utterance.html b/docs/_modules/dialogy/preprocess/text/normalize_utterance.html
index 61689993..cebbaf81 100644
--- a/docs/_modules/dialogy/preprocess/text/normalize_utterance.html
+++ b/docs/_modules/dialogy/preprocess/text/normalize_utterance.html
@@ -192,11 +192,11 @@ <h1>Source code for dialogy.preprocess.text.normalize_utterance</h1><div class="
 
 <div class="viewcode-block" id="is_list"><a class="viewcode-back" href="../../../../source/dialogy.preprocess.text.html#dialogy.preprocess.text.normalize_utterance.is_list">[docs]</a><span class="k">def</span> <span class="nf">is_list</span><span class="p">(</span><span class="n">input_</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
     <span class="sd">"""</span>
-<span class="sd">    Check type of `input_`</span>
+<span class="sd">    Check type of :code:`input`</span>
 
 <span class="sd">    :param input_: Any arbitrary input</span>
 <span class="sd">    :type input_: Any</span>
-<span class="sd">    :return: True if input_ is a :code:`list` else False</span>
+<span class="sd">    :return: True if :code:`input` is a :code:`list` else False</span>
 <span class="sd">    :rtype: True</span>
 <span class="sd">    """</span>
     <span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">input_</span><span class="p">,</span> <span class="nb">list</span><span class="p">)</span></div>
@@ -234,11 +234,14 @@ <h1>Source code for dialogy.preprocess.text.normalize_utterance</h1><div class="
 <div class="viewcode-block" id="is_utterance"><a class="viewcode-back" href="../../../../source/dialogy.preprocess.text.html#dialogy.preprocess.text.normalize_utterance.is_utterance">[docs]</a><span class="k">def</span> <span class="nf">is_utterance</span><span class="p">(</span><span class="n">maybe_utterance</span><span class="p">:</span> <span class="n">Any</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">const</span><span class="o">.</span><span class="n">TRANSCRIPT</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
     <span class="sd">"""</span>
 <span class="sd">    .. _is_utterance:</span>
+
 <span class="sd">    Check input to be of `List[List[Dict]]`.</span>
 
-<span class="sd">    ```json</span>
-<span class="sd">    [[{"transcript": "hi"}]]</span>
-<span class="sd">    ```</span>
+
+<span class="sd">    .. code-blocks: json</span>
+
+<span class="sd">        [[{"transcript": "hi"}]]</span>
+
 
 <span class="sd">    .. ipython:: python</span>
 
diff --git a/docs/_modules/dialogy/types/entity/base_entity.html b/docs/_modules/dialogy/types/entity/base_entity.html
index 361ae853..90817c7d 100644
--- a/docs/_modules/dialogy/types/entity/base_entity.html
+++ b/docs/_modules/dialogy/types/entity/base_entity.html
@@ -284,6 +284,35 @@ <h1>Source code for dialogy.types.entity.base_entity</h1><div class="highlight">
         <span class="k">for</span> <span class="n">prop</span><span class="p">,</span> <span class="n">prop_type</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__properties_map</span><span class="p">:</span>
             <span class="n">validate_type</span><span class="p">(</span><span class="n">traverse_dict</span><span class="p">(</span><span class="n">dict_</span><span class="p">,</span> <span class="n">prop</span><span class="p">),</span> <span class="n">prop_type</span><span class="p">)</span></div>
 
+<div class="viewcode-block" id="BaseEntity.reshape"><a class="viewcode-back" href="../../../../source/dialogy.types.entity.html#dialogy.types.entity.base_entity.BaseEntity.reshape">[docs]</a>    <span class="nd">@classmethod</span>
+    <span class="k">def</span> <span class="nf">reshape</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">dict_</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
+        <span class="sd">"""</span>
+<span class="sd">        :type dict_: Dict[str, Any]</span>
+<span class="sd">        """</span>
+        <span class="n">match_start</span> <span class="o">=</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">START</span><span class="p">]</span>
+        <span class="n">match_end</span> <span class="o">=</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">END</span><span class="p">]</span>
+
+        <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">RANGE</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
+            <span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">START</span><span class="p">:</span> <span class="n">match_start</span><span class="p">,</span>
+            <span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">END</span><span class="p">:</span> <span class="n">match_end</span><span class="p">,</span>
+        <span class="p">}</span>
+        <span class="c1"># ['body', 'start', 'value', 'end', 'dim', 'latent']</span>
+
+        <span class="c1"># **type** of an entity is same as its **dimension**.</span>
+        <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">TYPE</span><span class="p">]</span> <span class="o">=</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">DIM</span><span class="p">]</span>
+
+        <span class="c1"># This piece is a preparation for multiple entity values.</span>
+        <span class="c1"># So, even though we are confident of the value found, we are still keeping the</span>
+        <span class="c1"># structure.</span>
+        <span class="k">if</span> <span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUES</span> <span class="ow">in</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUE</span><span class="p">]:</span>
+            <span class="k">del</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUE</span><span class="p">][</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUES</span><span class="p">]</span>
+        <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUES</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUE</span><span class="p">]]</span>
+
+        <span class="k">del</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">START</span><span class="p">]</span>
+        <span class="k">del</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">END</span><span class="p">]</span>
+        <span class="k">del</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUE</span><span class="p">]</span>
+        <span class="k">return</span> <span class="n">dict_</span></div>
+
 <div class="viewcode-block" id="BaseEntity.from_dict"><a class="viewcode-back" href="../../../../source/dialogy.types.entity.html#dialogy.types.entity.base_entity.BaseEntity.from_dict">[docs]</a>    <span class="nd">@classmethod</span>
     <span class="k">def</span> <span class="nf">from_dict</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">dict_</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="s2">"BaseEntity"</span><span class="p">:</span>
         <span class="sd">"""</span>
@@ -297,6 +326,7 @@ <h1>Source code for dialogy.types.entity.base_entity</h1><div class="highlight">
 <span class="sd">        :return: Instance of class</span>
 <span class="sd">        :rtype: BaseEntity</span>
 <span class="sd">        """</span>
+        <span class="n">dict_</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">dict_</span><span class="p">)</span>
         <span class="bp">cls</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">dict_</span><span class="p">)</span>
         <span class="k">return</span> <span class="bp">cls</span><span class="p">(</span><span class="o">**</span><span class="n">dict_</span><span class="p">)</span></div>
 
diff --git a/docs/_modules/dialogy/types/entity/time_entity.html b/docs/_modules/dialogy/types/entity/time_entity.html
index 34f27237..530f7e55 100644
--- a/docs/_modules/dialogy/types/entity/time_entity.html
+++ b/docs/_modules/dialogy/types/entity/time_entity.html
@@ -171,11 +171,11 @@ <h1>Source code for dialogy.types.entity.time_entity</h1><div class="highlight">
 <span class="sd">Import classes:</span>
 <span class="sd">    - TimeEntity</span>
 <span class="sd">"""</span>
-<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Optional</span>
+<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Optional</span>
 
 <span class="kn">import</span> <span class="nn">attr</span>
 
-<span class="kn">from</span> <span class="nn">dialogy</span> <span class="kn">import</span> <span class="n">constants</span>
+<span class="kn">from</span> <span class="nn">dialogy</span> <span class="kn">import</span> <span class="n">constants</span> <span class="k">as</span> <span class="n">const</span>
 <span class="kn">from</span> <span class="nn">dialogy.types.entity.numerical_entity</span> <span class="kn">import</span> <span class="n">NumericalEntity</span>
 
 
@@ -195,7 +195,21 @@ <h1>Source code for dialogy.types.entity.time_entity</h1><div class="highlight">
 
     <span class="n">dim</span> <span class="o">=</span> <span class="s2">"time"</span>
     <span class="n">grain</span> <span class="o">=</span> <span class="n">attr</span><span class="o">.</span><span class="n">ib</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">validator</span><span class="o">=</span><span class="n">attr</span><span class="o">.</span><span class="n">validators</span><span class="o">.</span><span class="n">instance_of</span><span class="p">(</span><span class="nb">str</span><span class="p">))</span>
-    <span class="n">__properties_map</span> <span class="o">=</span> <span class="n">constants</span><span class="o">.</span><span class="n">TIME_ENTITY_PROPS</span>
+    <span class="n">__properties_map</span> <span class="o">=</span> <span class="n">const</span><span class="o">.</span><span class="n">TIME_ENTITY_PROPS</span>
+
+<div class="viewcode-block" id="TimeEntity.reshape"><a class="viewcode-back" href="../../../../source/dialogy.types.entity.html#dialogy.types.entity.time_entity.TimeEntity.reshape">[docs]</a>    <span class="nd">@classmethod</span>
+    <span class="k">def</span> <span class="nf">reshape</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">dict_</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
+        <span class="n">dict_</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">TimeEntity</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">dict_</span><span class="p">)</span>
+        <span class="c1"># Pulling out the value of entity's **grain**. The value of **grain** helps</span>
+        <span class="c1"># us understand the precision of the entity. Usually present for `Time` dimension</span>
+        <span class="c1"># expect "year", "month", "day", etc.</span>
+        <span class="k">if</span> <span class="nb">all</span><span class="p">(</span>
+            <span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">GRAIN</span> <span class="ow">in</span> <span class="n">value</span> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUES</span><span class="p">]</span>
+        <span class="p">):</span>
+            <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">GRAIN</span><span class="p">]</span> <span class="o">=</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUES</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span>
+                <span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">GRAIN</span>
+            <span class="p">]</span>
+        <span class="k">return</span> <span class="n">dict_</span></div>
 
     <span class="k">def</span> <span class="nf">__attrs_post_init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
         <span class="n">grain_</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
diff --git a/docs/_modules/dialogy/types/entity/time_interval_entity.html b/docs/_modules/dialogy/types/entity/time_interval_entity.html
index d09f92ca..a937da12 100644
--- a/docs/_modules/dialogy/types/entity/time_interval_entity.html
+++ b/docs/_modules/dialogy/types/entity/time_interval_entity.html
@@ -196,6 +196,21 @@ <h1>Source code for dialogy.types.entity.time_interval_entity</h1><div class="hi
     <span class="n">dim</span> <span class="o">=</span> <span class="s2">"time"</span>
     <span class="n">__properties_map</span> <span class="o">=</span> <span class="n">const</span><span class="o">.</span><span class="n">TIME_ENTITY_PROPS</span>
 
+<div class="viewcode-block" id="TimeIntervalEntity.reshape"><a class="viewcode-back" href="../../../../source/dialogy.types.entity.html#dialogy.types.entity.time_interval_entity.TimeIntervalEntity.reshape">[docs]</a>    <span class="nd">@classmethod</span>
+    <span class="k">def</span> <span class="nf">reshape</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">dict_</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
+        <span class="n">dict_</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">TimeIntervalEntity</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">dict_</span><span class="p">)</span>
+        <span class="k">if</span> <span class="nb">all</span><span class="p">(</span>
+            <span class="n">value</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">TYPE</span><span class="p">]</span> <span class="o">==</span> <span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">INTERVAL</span>
+            <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUES</span><span class="p">]</span>
+        <span class="p">):</span>
+            <span class="n">date_range</span> <span class="o">=</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUES</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
+                <span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">FROM</span>
+            <span class="p">)</span> <span class="ow">or</span> <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">VALUES</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">TO</span><span class="p">)</span>
+            <span class="k">if</span> <span class="ow">not</span> <span class="n">date_range</span><span class="p">:</span>
+                <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">dict_</span><span class="si">}</span><span class="s2"> does not match TimeIntervalEntity format"</span><span class="p">)</span>
+            <span class="n">dict_</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">GRAIN</span><span class="p">]</span> <span class="o">=</span> <span class="n">date_range</span><span class="p">[</span><span class="n">const</span><span class="o">.</span><span class="n">EntityKeys</span><span class="o">.</span><span class="n">GRAIN</span><span class="p">]</span>
+        <span class="k">return</span> <span class="n">dict_</span></div>
+
 <div class="viewcode-block" id="TimeIntervalEntity.set_value"><a class="viewcode-back" href="../../../../source/dialogy.types.entity.html#dialogy.types.entity.time_interval_entity.TimeIntervalEntity.set_value">[docs]</a>    <span class="k">def</span> <span class="nf">set_value</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
         <span class="sd">"""</span>
 <span class="sd">        Set values and value attribute.</span>
diff --git a/docs/_modules/dialogy/workflow/workflow.html b/docs/_modules/dialogy/workflow/workflow.html
index d9f1235b..eeeaa6db 100644
--- a/docs/_modules/dialogy/workflow/workflow.html
+++ b/docs/_modules/dialogy/workflow/workflow.html
@@ -178,7 +178,7 @@ <h1>Source code for dialogy.workflow.workflow</h1><div class="highlight"><pre>
 <span class="sd">`anything`? through it, it would pass through with a thud on the ground `(yes we assumed gravity)`.</span>
 
 <span class="sd">All good but that's not special? Why would anyone need that?</span>
-<span class="sd">----</span>
+<span class="sd">-------------------------------------------------------------</span>
 
 <span class="sd">A workflow allows flexibility, that's why. There is very little structure to it. We have:</span>
 
@@ -192,7 +192,7 @@ <h1>Source code for dialogy.workflow.workflow</h1><div class="highlight"><pre>
 <span class="sd">your :ref:`Workflow &lt;Workflow&gt;` won't judge you.</span>
 
 <span class="sd">Where's the sauce?</span>
-<span class="sd">----</span>
+<span class="sd">-------------------</span>
 
 <span class="sd">The :ref:`Plugin&lt;plugin&gt;` concept takes care of the sauciness 🍅 of this project. Any functionality can be bundled into</span>
 <span class="sd">a :ref:`Plugin&lt;plugin&gt;` and they are portable over to foreign workflows. A :ref:`Plugin&lt;plugin&gt;` proxies inputs through</span>
@@ -200,7 +200,7 @@ <h1>Source code for dialogy.workflow.workflow</h1><div class="highlight"><pre>
 <span class="sd">function (another argument for every :ref:`Plugin&lt;plugin&gt;`). These two functions define interactions between many many</span>
 <span class="sd">(sic) :ref:`Plugins&lt;plugin&gt;` without knowing the inner workings of a :ref:`Workflow &lt;workflow&gt;`.</span>
 
-<span class="sd">Take a look at :ref:`DucklingParser &lt;Duckling&gt;`, this plugin handles inputs, manages the default :code:`json` output</span>
+<span class="sd">Take a look at :ref:`DucklingPlugin &lt;duckling_plugin&gt;`, this plugin handles inputs, manages the default :code:`json` output</span>
 <span class="sd">into neatly bundled :ref:`BaseEntity &lt;base_entity&gt;` and other similar classes. Another plugin</span>
 <span class="sd">:ref:`RuleBasedSlotFillerPlugin&lt;rule_slot_filler&gt;` takes care of slot names and the entity types that should be filled</span>
 <span class="sd">within.</span>
diff --git a/docs/_modules/index.html b/docs/_modules/index.html
index c5850756..54a14198 100644
--- a/docs/_modules/index.html
+++ b/docs/_modules/index.html
@@ -167,7 +167,6 @@ <h1>All modules for which code is available</h1>
 <ul><li><a href="dialogy/cli.html">dialogy.cli</a></li>
 <ul><li><a href="dialogy/cli/project.html">dialogy.cli.project</a></li>
 </ul><li><a href="dialogy/constants.html">dialogy.constants</a></li>
-<li><a href="dialogy/parser/text/entity/duckling_parser.html">dialogy.parser.text.entity.duckling_parser</a></li>
 <li><a href="dialogy/plugin/plugin.html">dialogy.plugin.plugin</a></li>
 <li><a href="dialogy/postprocess/text/slot_filler/rule_slot_filler.html">dialogy.postprocess.text.slot_filler.rule_slot_filler</a></li>
 <li><a href="dialogy/postprocess/text/voting/intent_voting.html">dialogy.postprocess.text.voting.intent_voting</a></li>
diff --git a/docs/genindex.html b/docs/genindex.html
index 948d9ebf..659c96f5 100644
--- a/docs/genindex.html
+++ b/docs/genindex.html
@@ -512,8 +512,6 @@ <h2>D</h2>
           <li><a href="source/dialogy.types.entity.html#dialogy.types.entity.time_interval_entity.TimeIntervalEntity.dim">(dialogy.types.entity.time_interval_entity.TimeIntervalEntity attribute)</a>
 </li>
         </ul></li>
-        <li><a href="source/dialogy.parser.text.entity.html#dialogy.parser.text.entity.duckling_parser.DucklingParser">DucklingParser (class in dialogy.parser.text.entity.duckling_parser)</a>
-</li>
         <li><a href="source/dialogy.constants.html#dialogy.constants.EntityKeys.DURATION">DURATION (dialogy.constants.EntityKeys attribute)</a>
 </li>
         <li><a href="source/dialogy.types.entity.html#dialogy.types.entity.duration_entity.DurationEntity">DurationEntity (class in dialogy.types.entity.duration_entity)</a>
@@ -783,11 +781,9 @@ <h2>P</h2>
 </li>
         <li><a href="source/dialogy.plugin.html#dialogy.plugin.plugin.Plugin">Plugin (class in dialogy.plugin.plugin)</a>
 </li>
-        <li><a href="source/dialogy.parser.text.entity.html#dialogy.parser.text.entity.duckling_parser.DucklingParser.plugin">plugin() (dialogy.parser.text.entity.duckling_parser.DucklingParser method)</a>
+        <li><a href="source/dialogy.postprocess.text.slot_filler.html#dialogy.postprocess.text.slot_filler.rule_slot_filler.RuleBasedSlotFillerPlugin.plugin">plugin() (dialogy.postprocess.text.slot_filler.rule_slot_filler.RuleBasedSlotFillerPlugin method)</a>
 
         <ul>
-          <li><a href="source/dialogy.postprocess.text.slot_filler.html#dialogy.postprocess.text.slot_filler.rule_slot_filler.RuleBasedSlotFillerPlugin.plugin">(dialogy.postprocess.text.slot_filler.rule_slot_filler.RuleBasedSlotFillerPlugin method)</a>
-</li>
           <li><a href="source/dialogy.postprocess.text.voting.html#dialogy.postprocess.text.voting.intent_voting.VotePlugin.plugin">(dialogy.postprocess.text.voting.intent_voting.VotePlugin method)</a>
 </li>
         </ul></li>
@@ -809,6 +805,14 @@ <h2>R</h2>
 </li>
         <li><a href="source/dialogy.constants.html#dialogy.constants.SIGNAL.REPRESENTATION">REPRESENTATION (dialogy.constants.SIGNAL attribute)</a>
 </li>
+        <li><a href="source/dialogy.types.entity.html#dialogy.types.entity.base_entity.BaseEntity.reshape">reshape() (dialogy.types.entity.base_entity.BaseEntity class method)</a>
+
+        <ul>
+          <li><a href="source/dialogy.types.entity.html#dialogy.types.entity.time_entity.TimeEntity.reshape">(dialogy.types.entity.time_entity.TimeEntity class method)</a>
+</li>
+          <li><a href="source/dialogy.types.entity.html#dialogy.types.entity.time_interval_entity.TimeIntervalEntity.reshape">(dialogy.types.entity.time_interval_entity.TimeIntervalEntity class method)</a>
+</li>
+        </ul></li>
     </ul></td>
     <td style="width: 33%; vertical-align: top;"><ul>
         <li><a href="source/dialogy.postprocess.text.slot_filler.html#dialogy.postprocess.text.slot_filler.rule_slot_filler.RuleBasedSlotFillerPlugin">RuleBasedSlotFillerPlugin (class in dialogy.postprocess.text.slot_filler.rule_slot_filler)</a>
diff --git a/docs/objects.inv b/docs/objects.inv
index ab7567fb..ef15295f 100644
Binary files a/docs/objects.inv and b/docs/objects.inv differ
diff --git a/docs/searchindex.js b/docs/searchindex.js
index db696776..b7865ea7 100644
--- a/docs/searchindex.js
+++ b/docs/searchindex.js
@@ -1,1 +1,1 @@
-Search.setIndex({docnames:["index","source/dialogy","source/dialogy.cli","source/dialogy.constants","source/dialogy.parser","source/dialogy.parser.text","source/dialogy.parser.text.entity","source/dialogy.plugin","source/dialogy.postprocess","source/dialogy.postprocess.text","source/dialogy.postprocess.text.slot_filler","source/dialogy.postprocess.text.voting","source/dialogy.preprocess","source/dialogy.preprocess.text","source/dialogy.types","source/dialogy.types.entity","source/dialogy.types.intent","source/dialogy.types.plugin","source/dialogy.types.signal","source/dialogy.types.slots","source/dialogy.types.utterances","source/dialogy.utils","source/dialogy.workflow","source/modules"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst","source/dialogy.rst","source/dialogy.cli.rst","source/dialogy.constants.rst","source/dialogy.parser.rst","source/dialogy.parser.text.rst","source/dialogy.parser.text.entity.rst","source/dialogy.plugin.rst","source/dialogy.postprocess.rst","source/dialogy.postprocess.text.rst","source/dialogy.postprocess.text.slot_filler.rst","source/dialogy.postprocess.text.voting.rst","source/dialogy.preprocess.rst","source/dialogy.preprocess.text.rst","source/dialogy.types.rst","source/dialogy.types.entity.rst","source/dialogy.types.intent.rst","source/dialogy.types.plugin.rst","source/dialogy.types.signal.rst","source/dialogy.types.slots.rst","source/dialogy.types.utterances.rst","source/dialogy.utils.rst","source/dialogy.workflow.rst","source/modules.rst"],objects:{"":{dialogy:[1,0,0,"-"]},"dialogy.cli":{main:[2,1,1,""],project:[2,0,0,"-"]},"dialogy.cli.project":{new_project:[2,1,1,""]},"dialogy.constants":{EntityKeys:[3,2,1,""],SIGNAL:[3,2,1,""]},"dialogy.constants.EntityKeys":{BODY:[3,3,1,""],DIM:[3,3,1,""],DURATION:[3,3,1,""],END:[3,3,1,""],FROM:[3,3,1,""],GRAIN:[3,3,1,""],INTERVAL:[3,3,1,""],LATENT:[3,3,1,""],ORIGIN:[3,3,1,""],RANGE:[3,3,1,""],SLOT_NAMES:[3,3,1,""],START:[3,3,1,""],TO:[3,3,1,""],TYPE:[3,3,1,""],UNIT:[3,3,1,""],VALUE:[3,3,1,""],VALUES:[3,3,1,""]},"dialogy.constants.SIGNAL":{NAME:[3,3,1,""],REPRESENTATION:[3,3,1,""],STRENGTH:[3,3,1,""]},"dialogy.parser":{text:[5,0,0,"-"]},"dialogy.parser.text":{entity:[6,0,0,"-"]},"dialogy.parser.text.entity":{duckling_parser:[6,0,0,"-"]},"dialogy.parser.text.entity.duckling_parser":{DucklingParser:[6,2,1,""]},"dialogy.parser.text.entity.duckling_parser.DucklingParser":{plugin:[6,4,1,""]},"dialogy.plugin":{plugin:[7,0,0,"-"]},"dialogy.plugin.plugin":{Plugin:[7,2,1,""]},"dialogy.postprocess":{text:[9,0,0,"-"]},"dialogy.postprocess.text":{slot_filler:[10,0,0,"-"],voting:[11,0,0,"-"]},"dialogy.postprocess.text.slot_filler":{rule_slot_filler:[10,0,0,"-"]},"dialogy.postprocess.text.slot_filler.rule_slot_filler":{RuleBasedSlotFillerPlugin:[10,2,1,""]},"dialogy.postprocess.text.slot_filler.rule_slot_filler.RuleBasedSlotFillerPlugin":{plugin:[10,4,1,""]},"dialogy.postprocess.text.voting":{intent_voting:[11,0,0,"-"]},"dialogy.postprocess.text.voting.intent_voting":{VotePlugin:[11,2,1,""],adjust_signal_strength:[11,1,1,""]},"dialogy.postprocess.text.voting.intent_voting.VotePlugin":{plugin:[11,4,1,""],vote_signal:[11,4,1,""]},"dialogy.preprocess":{text:[13,0,0,"-"]},"dialogy.preprocess.text":{merge_asr_output:[13,0,0,"-"],normalize_utterance:[13,0,0,"-"]},"dialogy.preprocess.text.merge_asr_output":{merge_asr_output:[13,1,1,""],merge_asr_output_plugin:[13,1,1,""]},"dialogy.preprocess.text.normalize_utterance":{dict_get:[13,1,1,""],is_each_element:[13,1,1,""],is_list:[13,1,1,""],is_list_of_string:[13,1,1,""],is_string:[13,1,1,""],is_unsqueezed_utterance:[13,1,1,""],is_utterance:[13,1,1,""],normalize:[13,1,1,""]},"dialogy.types":{entity:[15,0,0,"-"],intent:[16,0,0,"-"],plugin:[17,0,0,"-"],signal:[18,0,0,"-"],slots:[19,0,0,"-"],utterances:[20,0,0,"-"]},"dialogy.types.entity":{base_entity:[15,0,0,"-"],duration_entity:[15,0,0,"-"],location_entity:[15,0,0,"-"],numerical_entity:[15,0,0,"-"],people_entity:[15,0,0,"-"],time_entity:[15,0,0,"-"],time_interval_entity:[15,0,0,"-"]},"dialogy.types.entity.base_entity":{BaseEntity:[15,2,1,""],entity_synthesis:[15,1,1,""]},"dialogy.types.entity.base_entity.BaseEntity":{add_parser:[15,4,1,""],copy:[15,4,1,""],entity_type:[15,3,1,""],from_dict:[15,4,1,""],get_value:[15,4,1,""],json:[15,4,1,""],set_value:[15,4,1,""],validate:[15,4,1,""],value:[15,3,1,""]},"dialogy.types.entity.duration_entity":{DurationEntity:[15,2,1,""]},"dialogy.types.entity.duration_entity.DurationEntity":{entity_type:[15,3,1,""],value:[15,3,1,""]},"dialogy.types.entity.location_entity":{LocationEntity:[15,2,1,""]},"dialogy.types.entity.location_entity.LocationEntity":{entity_type:[15,3,1,""],value:[15,3,1,""]},"dialogy.types.entity.numerical_entity":{NumericalEntity:[15,2,1,""]},"dialogy.types.entity.numerical_entity.NumericalEntity":{entity_type:[15,3,1,""],value:[15,3,1,""]},"dialogy.types.entity.people_entity":{PeopleEntity:[15,2,1,""]},"dialogy.types.entity.people_entity.PeopleEntity":{entity_type:[15,3,1,""],value:[15,3,1,""]},"dialogy.types.entity.time_entity":{TimeEntity:[15,2,1,""]},"dialogy.types.entity.time_entity.TimeEntity":{dim:[15,3,1,""],entity_type:[15,3,1,""],value:[15,3,1,""]},"dialogy.types.entity.time_interval_entity":{TimeIntervalEntity:[15,2,1,""]},"dialogy.types.entity.time_interval_entity.TimeIntervalEntity":{dim:[15,3,1,""],entity_type:[15,3,1,""],origin:[15,3,1,""],set_value:[15,4,1,""],value:[15,3,1,""]},"dialogy.types.intent":{Intent:[16,2,1,""]},"dialogy.types.intent.Intent":{add_parser:[16,4,1,""],apply:[16,4,1,""],cleanup:[16,4,1,""],fill_slot:[16,4,1,""],json:[16,4,1,""]},"dialogy.types.signal":{signal:[18,0,0,"-"]},"dialogy.types.slots":{Slot:[19,2,1,""]},"dialogy.types.slots.Slot":{add:[19,4,1,""],clear:[19,4,1,""],json:[19,4,1,""]},"dialogy.utils":{logger:[21,0,0,"-"],traverse_dict:[21,1,1,""],validate_type:[21,1,1,""]},"dialogy.utils.logger":{change_log_level:[21,1,1,""],debug_logs:[21,1,1,""]},"dialogy.workflow":{workflow:[22,0,0,"-"]},"dialogy.workflow.workflow":{Workflow:[22,2,1,""]},"dialogy.workflow.workflow.Workflow":{flush:[22,4,1,""],inference:[22,4,1,""],load_model:[22,4,1,""],postprocess:[22,4,1,""],preprocess:[22,4,1,""],run:[22,4,1,""],update:[22,4,1,""]},dialogy:{cli:[2,0,0,"-"],constants:[3,0,0,"-"],parser:[4,0,0,"-"],plugin:[7,0,0,"-"],postprocess:[8,0,0,"-"],preprocess:[12,0,0,"-"],types:[14,0,0,"-"],utils:[21,0,0,"-"],workflow:[22,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","attribute","Python attribute"],"4":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:attribute","4":"py:method"},terms:{"556a11057179":21,"639":6,"6th":15,"8000":6,"abstract":[7,22],"case":[6,7,11,13,15,16,22],"class":[0,3,6,7,10,11,15,16,19,21,22],"const":[13,15],"default":[2,6,11,13,15,22],"export":0,"final":22,"float":[6,11,13,15,16],"function":[2,6,7,11,13,15,16,21,22],"import":[0,3,6,10,11,13,15,16,17,19,20,21],"int":[11,15,16,21],"long":22,"new":[2,15],"return":[2,6,10,11,13,15,16,19,21,22],"static":7,"true":[10,11,13,16,21,22],"try":21,"while":[7,11,15],Its:15,LMs:13,Not:10,One:[21,22],That:13,The:[2,6,7,11,13,15,16,21,22],There:[6,14,16,21,22],These:[7,13,15,22],Use:[11,15,22],Uses:22,__call__:6,__init__:[2,7,21],__postprocessor:22,__preprocessor:22,__valid:15,_oos_:11,_plugin:7,abl:13,abort:2,about:[6,11],accept:0,access:[6,7,10,11,13,15,17,21,22],across:6,act:14,action:[10,16,22],action_slot:10,adapt:13,add:[15,19],add_pars:[15,16],added:15,addit:[7,10],address:[6,13,15],adjust_signal_strength:11,advanc:22,affect:0,affirm:11,after:[0,15,22],against:22,aggreg:11,aggregate_fn:11,agnost:0,ahead:15,aim:22,air:14,algorithm:11,all:[1,6,11,13,15,19,21],allow:[10,11,22],alpha2:6,alreadi:[2,14],also:[6,15],altern:[11,13,20],alternative_index:[10,15,16],analog:21,ani:[2,6,7,10,11,13,15,16,19,21,22],anomali:11,anoth:22,anticip:22,anyon:1,anyth:22,apart:22,api:[6,7],appli:[7,13,15,16,21],applic:[0,22],arbitrari:[13,15,22],arg:[15,21,22],arg_nam:21,argument:[11,13,22],arrang:10,artifact:[6,13],asia:6,ask:13,asr:[11,13],assert:21,assist:[10,13],associ:[10,14,16],assum:[7,22],assumpt:0,attempt:11,attr_nam:21,attribut:[15,16,21,22],audio:13,avail:[6,15,21],back:21,bad:22,base:[0,3,6,7,10,11,15,16,19,22],base_ent:[1,14,16,19],base_entity_prop:3,baseent:[6,10,15,16,19,22],battri:0,becaus:[6,22],been:22,beep:21,befor:[13,22],being:[7,11,15,21],best:[11,13],better:7,between:[10,14,15,22],beyond:11,bit:10,bloat:15,block:22,bodi:[3,10,15,16],boilerpl:0,book:15,bool:[6,7,10,11,13,15,16,22],boost:11,booster:11,bop:21,both:15,box:7,briefli:21,build:[0,22],built:[7,11],bunch:22,bundl:22,call:[6,15,16,21],callabl:[6,7,10,11,13,15,16,21,22],can:[0,6,7,10,11,13,14,15,16,19,22],candid:11,care:22,categori:10,caution:[11,13,15],certain:[6,10,13],challeng:7,chanc:13,chang:[7,15,21,22],change_log_level:21,check:[6,10,13,15,16,21,22],children:15,choic:[0,22],classifi:[10,11,22],classmethod:15,cleanup:16,clear:19,cli:[0,1,23],cls:15,code:[0,6,13],collat:22,collect:[0,15],com:[10,13],command:2,common:13,compat:10,compli:15,complianc:15,compon:0,comput:22,concat:13,concaten:[11,13],conceal:15,concept:22,condit:[21,22],conduit:22,confid:11,configur:[10,13,16,21],connect:6,consensu:11,consid:[11,14],consider:[11,22],consist:6,constant:[0,1,23],constitu:11,constraint:22,contain:[10,11,15,16],content:[0,23],context:7,contextu:11,continu:11,conveni:[7,22],convent:7,convers:14,convert:[15,16,19],copi:[2,15],copier:2,core:22,corpu:7,corpus_dir:7,corpus_fil:7,cost:13,could:[11,22],count:11,count_peopl:10,counterpart:11,countri:6,coupl:[15,22],cover:[13,15],creat:[0,2,6,7,10,13,15,16],critic:21,currenc:6,current:[2,10,15,19,22],custom:7,customplugin:7,cuz:13,dai:15,dampen:11,data:[2,6,13,15],databas:6,dataset:2,date:[6,14,15],datetim:15,debug:[6,7,10,11,15,16,21,22],debug_log:21,decemb:15,decid:11,decor:21,deep:15,deepli:21,def:[6,7,11],defin:[6,10,11,13,15,17,22],definit:[13,16,19],demo:[16,22],denot:15,depend:[15,22],depict:11,deploi:6,describ:21,design:[7,10,11,22],desir:22,destin:14,destination_path:2,detail:[0,13,16],develop:13,dialog:10,dict:[6,10,13,15,16,19,21],dict_:15,dict_get:13,dict_travers:21,dictionari:[15,16,19,21],did:11,differ:[6,7,11,13,15,16],dim:[3,10,15],dimens:[6,15],dir:2,directli:[7,22],directori:2,dissimilar:13,document:13,doe:10,doesn:[13,15,21],don:[7,21],down:6,downstream:13,drop:22,duckl:[6,15],duckling_ent:6,duckling_pars:[4,5],duckling_plugin:6,ducklingpars:[6,7,22],due:21,durat:[3,6,15],duration_ent:[1,14],durationent:15,dynam:7,each:[10,11,13,15],eas:11,easi:0,either:[14,15,21],elect:11,element:[10,13,15,21,22],els:[11,13],emit:11,en_gb:6,en_in:6,en_u:6,encourag:7,end:[3,7,10,13],enforc:22,english:10,entiti:[1,4,5,10,14,16,19,21,22],entity_synthesi:15,entity_typ:[10,15],entitykei:3,error:21,especi:6,etc:[6,22],evalu:11,even:[7,10],everi:22,everyth:13,evid:11,exampl:[2,6,7,10,14,15],except:21,exclus:21,execut:[21,22],exhibit:[2,22],exist:[2,7,13,21],expect:[6,7,10,11,13,14,15,22],experi:6,explicitli:15,explor:16,expos:[2,6,7],express:6,extend:7,extern:7,extra:6,extract:[6,10,19],facilit:13,fact:13,fail:[11,13],fairli:22,fallback:11,fallback_int:11,fals:[6,7,10,11,13,15,16,22],faq:10,featur:7,few:[0,7,10,14,22],field:6,file:2,file_path:7,fill:[10,14,16,19,22],fill_multipl:[10,16],fill_slot:16,filler:10,filter:[11,15,22],find:11,fine:13,first:21,flag:21,flatten:13,flavor:15,flexibl:22,flight:15,flush:22,focu:0,follow:22,foreign:22,forest:11,fork:6,form:13,format:[6,10,13],found:10,framework:0,free:[6,7],frequenc:11,from:[2,3,6,7,10,11,13,15,16,21,22],from_dict:15,func:21,gap:11,gener:[2,11,14],geographi:6,geopointent:15,get:[0,6,10,13,15,22],get_valu:15,getworkflowutterancefn:[13,17],github:13,given:[2,13,15,21],goe:11,good:1,grain:[3,15],graviti:22,great:13,ground:22,group:11,guid:6,had:11,hamper:7,handl:[7,10,11,13,15,22],hang:22,has:[7,11,15,16],have:[0,6,10,11,13,15,16,21,22],healthi:11,hello:[2,13],help:[0,2,6,7,11,13,15,16],here:[2,6,7,11,13,22],heurist:11,high:11,hold:16,hollow:22,hope:[7,13],how:11,html:10,http:[6,10,13],ideal:[7,11,22],ident:13,identifi:[10,15,16],ids:[6,15],impact:13,imper:6,implement:[6,7,15,22],impli:[11,13,21],improv:[7,11,13],includ:[0,15],inconsequenti:13,index:[0,21],indexerror:[15,21],infer:22,info:[6,21],inform:[11,13,15,18],inner:22,input:[6,7,10,11,13,15,21,22],input_:[6,7,10,11,13,21,22],insert:[6,7,19],instal:2,instanc:[6,7,11,15,16,19,21],instanti:[6,10,15],instead:[13,21],intend:15,intent:[1,10,11,14,22],intent_detection_slot_fil:10,intent_nam:10,intent_vot:[8,9],interact:[0,7,22],interfac:6,intermedi:11,interv:[3,15],invoc:2,invok:6,ipython:21,irrespect:10,is_each_el:13,is_list:13,is_list_of_str:13,is_str:13,is_unsqueezed_utter:13,is_utter:13,isn:[6,10,22],iso3166:6,iso:6,isol:7,issu:[13,15],item:10,iter:22,its:[6,7,10,11,15,16],join:[7,13],json:[13,15,16,19,22],judg:22,just:[6,7,13],keep:7,kei:[6,7,13,15,19],key_error:21,keyerror:[15,21],know:[13,22],known:15,kolkata:6,kwarg:21,lambda:[6,10,11,13,21],languag:[6,21,22],largest:22,last:21,latent:[3,10,15],latitud:15,lead:[11,21],learn:[0,11,22],leav:13,len:11,let:[0,10,11],level:[21,22],lib:13,librari:0,light:22,like:[6,7,10,11,13,14,15],line:[2,6],link:2,lint:2,list:[6,10,11,13,15,16,19,21,22],littl:22,load:[7,22],load_corpu:7,load_model:22,local:6,locat:[2,15],location_ent:[1,14],locationent:[10,15],log:[11,21,22],logger:[1,23],logic:21,longitud:15,look:[10,11,13,22],machin:[0,22],made:[0,7,11],mai:[10,13,22],main:2,make:[0,2,6,13,15,21,22],manag:22,mani:[11,22],map:10,mar:21,mark:13,mastercard:13,match:[6,10,13,15,21],mayb:16,maybe_utter:13,mean:[6,11,14,16],meant:15,medium:22,merg:13,merge_asr_output:[1,12],merge_asr_output_plugin:[7,13],met:[7,11],meta:15,method:[6,7,10,15,21,22],metric:2,minim:0,mismatch:21,miss:[2,13,21],mock:[11,22],model:[2,10,11,13,22],modif:[7,15,16],modifi:[11,16,22],modul:[0,23],more:[6,10,11,13,15,22],most:[13,21],multipl:[6,11,13,16],must:[2,7,21],mutat:[6,7,10,11,13,15,22],naiv:11,name:[2,3,6,7,10,11,15,16,19,21,22],namespac:2,navig:21,neatli:22,necessari:15,need:[1,6,10,11,13,15,21],neg:11,neither:21,nest:21,new_project:2,nlp:13,nlpprogress:10,nois:13,non:13,none:[2,6,7,10,11,13,15,16,21,22],nonetyp:2,normal:[10,11,13,15],normalize_utter:[1,12],note:6,noth:[11,15],notic:[6,10,11,13],notimplementederror:22,now:11,number:[6,10,11,14,15,22],number_ent:10,number_slot:10,numer:[6,15],numerical_ent:[1,14],numericalent:[10,15],obj:[13,21],obj_typ:21,object:[3,6,7,15,16,19,21,22],observ:11,obtain:[11,15],occurr:11,offer:[2,7,22],onc:[6,7,10],one:[6,10,11,14],ones:22,onli:[6,10,11,13,21],open:[7,15],oper:[6,13,15],opinion:0,option:[2,6,7,10,11,13,15,16,22],organ:2,origin:[3,10,14,15],other:[0,10,11,15,22],out:[10,11,13,16,21],output:[6,7,10,11,13,22],over:[11,22],overal:[6,11],overrid:[15,22],overridden:[15,22],owing:13,own:15,packag:[0,23],page:0,paint:11,param:21,paramet:[2,6,10,11,13,15,16,21,22],pars:[6,13,15,21],parser:[0,1,10,15,16,23],part:6,parti:7,partial:13,particip:14,pass:[6,10,11,21,22],passeng:14,path:[7,21,22],pattern:6,peopl:[6,7,10,15],people_ent:[1,10,14],people_entity_prop:3,peopleent:[10,15],per:[6,7,10],percentag:11,perform:13,pertain:10,pick:11,pictur:11,pip:0,pipe:22,pipelin:[7,22],place:[6,7,11,13,22],plain:11,planet:21,plugin:[0,1,6,10,11,13,14,15,16,22,23],pluginfn:[7,10,11,15,16,17,22],poetri:2,point:[2,7,11],poor:11,popular:0,portabl:[7,22],posit:13,possibl:[16,21],post:[7,22],postprocess:[0,1,15,16,22,23],postprocessor:[3,10,11,15,16,22],pprint:10,practic:10,pre:[7,10,17,22],precis:13,predict:[11,22],prefer:[16,21],preprocess:[0,1,22,23],preprocessor:[3,6,10,11,22],present:10,preset:10,prevent:[6,15],privat:6,problem:[0,13],procedur:22,process:[6,7,22],processor:22,processor_typ:22,produc:[11,13],product:[11,15,16],progress:[0,14,15,16],project:[1,3,14,21,22,23],prop:13,properti:[6,13,15,21],property_:15,proport:11,provid:[3,6,7,10,11,13,15,17,18,20,21],proxi:22,purpos:15,put:22,python:21,pytz:6,rais:[10,11,13,15,21,22],rang:[3,10,15,21],rank:11,reach:6,read:[6,7],readi:[0,11],recal:13,receiv:[11,22],recent:21,recurs:21,reduc:[11,21],refer:[13,15],relai:22,relat:[6,10],relationship:[10,14],remain:11,remov:[16,19],replac:15,report:10,repres:[10,13],represent:[3,11,15],requir:[6,7,13,14,22],reserv:14,reset:22,resid:13,resort:11,respect:[13,14,15],respons:[6,13],restrict:[7,21,22],result:22,review:0,root:2,round:14,rtype:[15,21],rule:[10,16],rule_slot_fil:[8,9],rule_str:10,rulebasedslotfillerplugin:[7,10,16,22],ruleslotfilerplugin:7,run:[6,7,10,11,21,22],runtim:7,safe:[7,11,15],safe_load:10,safeguard:22,safest:11,sai:[11,22],said:15,same:[7,16],sauc:1,sauci:22,scaffold:[0,2],schema:10,score:[10,11,15,16],screen:2,search:[0,6],second:15,section:[6,14,15],see:22,self:7,semant:13,sentenc:[6,13,14,15],sentence2vecplugin:7,separ:[7,13],server:6,servic:6,session:0,set:[6,7,10,11,14,15,16,21],set_valu:15,shall:10,share:16,shift:22,ship:[7,13],should:[6,10,11,13,15,16,22],show:2,sic:22,signal:[1,3,11,14],signatur:[10,22],signific:[10,13,14],similar:[11,13,22],simpl:[0,2,7,13,22],simpli:13,simul:11,sinc:[7,11,13],singl:[10,11,13,16],situat:11,size:11,skip:15,skip_entity_attr:15,slot:[1,10,11,14,16,22],slot_fil:[8,9],slot_nam:[3,10,15],slot_rul:10,slot_typ:16,slow:6,slu:[0,11,14,22],smallest:15,solut:[0,7],some:[7,11,13,15,22],somewher:6,sort:22,sourc:[2,3,6,7,10,11,13,15,16,19,21,22],sparingli:21,speaker:21,special:[1,16],specif:[6,15,21],specifi:[2,6,7],speech:0,splitlin:7,stack:0,stage:7,stall:6,standard:[6,13],start:[2,3,10,13],state:[11,13],statist:22,str:[2,6,7,10,11,13,15,16,19,21,22],strategi:13,strength:[3,11],string:[6,11,13],strong:11,stronger:22,structur:[7,13,15,22],sub:[0,22],subclass:[6,15,22],submodul:[1,4,5,8,9,12,14,23],subpackag:[0,23],sugar:[6,15,21],summar:7,supplier:22,support:[2,6,13,15,16,22],suppos:[15,22],sure:6,syntact:6,syntat:21,synthet:10,system:[10,13],tailor:7,take:[11,22],task:[13,22],tell:[10,11,14,15],templat:[0,2],tend:[6,13],termin:13,text:[1,4,8,12,16],than:[10,11],thei:[13,22],them:[7,10,13,21],therefor:7,thi:[2,6,7,10,11,13,14,15,16,18,19,21,22],think:22,third:[7,10],those:[6,15,21,22],though:13,threshold:11,through:[6,10,15,22],throughout:[7,21],throughtout:3,thud:22,ticket:14,time:[6,10,14,15,21],time_ent:[1,14],time_entity_prop:3,time_interval_ent:[1,14],time_slot:10,timeent:[10,15],timeinterv:6,timeintervalent:15,timeout:6,timestamp:15,timezon:6,todai:15,token:[10,11,14,15],top:11,total:11,traceback:21,transcript:[11,13],transform:[0,2,6,13],travel:14,travers:21,traverse_dict:21,tree:11,trial:11,trip:14,triplet:15,tupl:[10,11,21],two:[10,11,15,21,22],type:[0,1,2,3,6,10,11,13,21,22,23],type_:13,typeerror:[10,11,13,21,22],umm:13,unawar:7,under:[11,13],understand:16,union:[13,21],uniqu:[11,13],unit:[3,10,15],unk:11,unless:10,unsaf:[11,15],unset:13,updat:[7,10,15,16,21,22],update_int:11,update_workflow:6,updateworkflowstringfn:[13,17],upon:14,url:6,usag:[2,7],use:[0,2,7,10,13,14,22],used:[3,6,13,15,21,22],useful:[7,21],user:2,uses:2,using:[0,2,6,11,15,16,21,22],usual:7,util:[0,1,2,10,11,15,16,23],utter:[1,13,14,15],valid:[6,15],validate_typ:21,valu:[3,6,7,10,11,13,15,16,19,21,22],variant:15,variou:[7,13],vector:13,veri:[11,13,22],verifi:15,vernacular:[2,13],version:[2,22],vertic:22,via:[7,21],vote:[8,9],vote_plugin:11,vote_sign:11,voteintentplugin:11,voteplugin:[7,11,13,22],wai:[7,11,14,21],want:[13,15,16,22],warn:21,weak:11,weight:11,well:[6,13,22],were:[6,15,16,22],when:6,where:[1,2,6,11,13,15,16],which:[6,11,13,15,16,22],whole:15,why:1,win:11,wish:15,within:[6,13,14,15,16,19,21,22],without:[21,22],won:[7,22],words2num_plugin:7,work:[13,14,22],workflow:[0,1,6,7,10,11,13,23],workflow_public_properti:3,world:[2,13],worri:22,worst:11,would:[1,6,13,14],wrap:21,wrapper:21,write:[0,7],written:7,yaml:10,yep:11,yes:[11,22],yet:11,yield:11,you:[0,10,13,14,22],your:[0,22],your_project_nam:0},titles:["Welcome to dialogy\u2019s documentation!","dialogy package","dialogy.cli package","dialogy.constants package","dialogy.parser package","dialogy.parser.text package","dialogy.parser.text.entity package","dialogy.plugin package","dialogy.postprocess package","dialogy.postprocess.text package","dialogy.postprocess.text.slot_filler package","dialogy.postprocess.text.voting package","dialogy.preprocess package","dialogy.preprocess.text package","dialogy.types package","dialogy.types.entity package","dialogy.types.intent package","dialogy.types.plugin package","dialogy.types.signal package","dialogy.types.slots package","dialogy.types.utterances package","dialogy.utils package","dialogy.workflow package","dialogy"],titleterms:{all:22,anyon:22,base_ent:15,cli:2,constant:3,content:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22],dialogi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],document:0,duckling_pars:6,duration_ent:15,entiti:[6,15],faq:0,good:22,indic:0,instal:0,intent:16,intent_vot:11,location_ent:15,logger:21,merge_asr_output:13,modul:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22],need:22,normalize_utter:13,numerical_ent:15,packag:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22],parser:[4,5,6],people_ent:15,plugin:[7,17],postprocess:[8,9,10,11],preprocess:[12,13],project:[0,2],rule_slot_fil:10,sauc:22,signal:18,slot:19,slot_fil:10,special:22,start:0,submodul:[2,6,7,10,11,13,15,18,21,22],subpackag:[1,4,5,8,9,12,14],tabl:0,test:0,text:[5,6,9,10,11,13],time_ent:15,time_interval_ent:15,type:[14,15,16,17,18,19,20],util:21,utter:20,vote:11,welcom:0,where:22,why:22,workflow:22,would:22}})
\ No newline at end of file
+Search.setIndex({docnames:["index","source/dialogy","source/dialogy.cli","source/dialogy.constants","source/dialogy.parser","source/dialogy.parser.text","source/dialogy.parser.text.entity","source/dialogy.plugin","source/dialogy.postprocess","source/dialogy.postprocess.text","source/dialogy.postprocess.text.slot_filler","source/dialogy.postprocess.text.voting","source/dialogy.preprocess","source/dialogy.preprocess.text","source/dialogy.types","source/dialogy.types.entity","source/dialogy.types.intent","source/dialogy.types.plugin","source/dialogy.types.signal","source/dialogy.types.slots","source/dialogy.types.utterances","source/dialogy.utils","source/dialogy.workflow","source/modules"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst","source/dialogy.rst","source/dialogy.cli.rst","source/dialogy.constants.rst","source/dialogy.parser.rst","source/dialogy.parser.text.rst","source/dialogy.parser.text.entity.rst","source/dialogy.plugin.rst","source/dialogy.postprocess.rst","source/dialogy.postprocess.text.rst","source/dialogy.postprocess.text.slot_filler.rst","source/dialogy.postprocess.text.voting.rst","source/dialogy.preprocess.rst","source/dialogy.preprocess.text.rst","source/dialogy.types.rst","source/dialogy.types.entity.rst","source/dialogy.types.intent.rst","source/dialogy.types.plugin.rst","source/dialogy.types.signal.rst","source/dialogy.types.slots.rst","source/dialogy.types.utterances.rst","source/dialogy.utils.rst","source/dialogy.workflow.rst","source/modules.rst"],objects:{"":{dialogy:[1,0,0,"-"]},"dialogy.cli":{main:[2,1,1,""],project:[2,0,0,"-"]},"dialogy.cli.project":{new_project:[2,1,1,""]},"dialogy.constants":{EntityKeys:[3,2,1,""],SIGNAL:[3,2,1,""]},"dialogy.constants.EntityKeys":{BODY:[3,3,1,""],DIM:[3,3,1,""],DURATION:[3,3,1,""],END:[3,3,1,""],FROM:[3,3,1,""],GRAIN:[3,3,1,""],INTERVAL:[3,3,1,""],LATENT:[3,3,1,""],ORIGIN:[3,3,1,""],RANGE:[3,3,1,""],SLOT_NAMES:[3,3,1,""],START:[3,3,1,""],TO:[3,3,1,""],TYPE:[3,3,1,""],UNIT:[3,3,1,""],VALUE:[3,3,1,""],VALUES:[3,3,1,""]},"dialogy.constants.SIGNAL":{NAME:[3,3,1,""],REPRESENTATION:[3,3,1,""],STRENGTH:[3,3,1,""]},"dialogy.parser":{text:[5,0,0,"-"]},"dialogy.parser.text":{entity:[6,0,0,"-"]},"dialogy.parser.text.entity":{duckling_parser:[6,0,0,"-"]},"dialogy.plugin":{plugin:[7,0,0,"-"]},"dialogy.plugin.plugin":{Plugin:[7,2,1,""]},"dialogy.postprocess":{text:[9,0,0,"-"]},"dialogy.postprocess.text":{slot_filler:[10,0,0,"-"],voting:[11,0,0,"-"]},"dialogy.postprocess.text.slot_filler":{rule_slot_filler:[10,0,0,"-"]},"dialogy.postprocess.text.slot_filler.rule_slot_filler":{RuleBasedSlotFillerPlugin:[10,2,1,""]},"dialogy.postprocess.text.slot_filler.rule_slot_filler.RuleBasedSlotFillerPlugin":{plugin:[10,4,1,""]},"dialogy.postprocess.text.voting":{intent_voting:[11,0,0,"-"]},"dialogy.postprocess.text.voting.intent_voting":{VotePlugin:[11,2,1,""],adjust_signal_strength:[11,1,1,""]},"dialogy.postprocess.text.voting.intent_voting.VotePlugin":{plugin:[11,4,1,""],vote_signal:[11,4,1,""]},"dialogy.preprocess":{text:[13,0,0,"-"]},"dialogy.preprocess.text":{merge_asr_output:[13,0,0,"-"],normalize_utterance:[13,0,0,"-"]},"dialogy.preprocess.text.merge_asr_output":{merge_asr_output:[13,1,1,""],merge_asr_output_plugin:[13,1,1,""]},"dialogy.preprocess.text.normalize_utterance":{dict_get:[13,1,1,""],is_each_element:[13,1,1,""],is_list:[13,1,1,""],is_list_of_string:[13,1,1,""],is_string:[13,1,1,""],is_unsqueezed_utterance:[13,1,1,""],is_utterance:[13,1,1,""],normalize:[13,1,1,""]},"dialogy.types":{entity:[15,0,0,"-"],intent:[16,0,0,"-"],plugin:[17,0,0,"-"],signal:[18,0,0,"-"],slots:[19,0,0,"-"],utterances:[20,0,0,"-"]},"dialogy.types.entity":{base_entity:[15,0,0,"-"],duration_entity:[15,0,0,"-"],location_entity:[15,0,0,"-"],numerical_entity:[15,0,0,"-"],people_entity:[15,0,0,"-"],time_entity:[15,0,0,"-"],time_interval_entity:[15,0,0,"-"]},"dialogy.types.entity.base_entity":{BaseEntity:[15,2,1,""],entity_synthesis:[15,1,1,""]},"dialogy.types.entity.base_entity.BaseEntity":{add_parser:[15,4,1,""],copy:[15,4,1,""],entity_type:[15,3,1,""],from_dict:[15,4,1,""],get_value:[15,4,1,""],json:[15,4,1,""],reshape:[15,4,1,""],set_value:[15,4,1,""],validate:[15,4,1,""],value:[15,3,1,""]},"dialogy.types.entity.duration_entity":{DurationEntity:[15,2,1,""]},"dialogy.types.entity.duration_entity.DurationEntity":{entity_type:[15,3,1,""],value:[15,3,1,""]},"dialogy.types.entity.location_entity":{LocationEntity:[15,2,1,""]},"dialogy.types.entity.location_entity.LocationEntity":{entity_type:[15,3,1,""],value:[15,3,1,""]},"dialogy.types.entity.numerical_entity":{NumericalEntity:[15,2,1,""]},"dialogy.types.entity.numerical_entity.NumericalEntity":{entity_type:[15,3,1,""],value:[15,3,1,""]},"dialogy.types.entity.people_entity":{PeopleEntity:[15,2,1,""]},"dialogy.types.entity.people_entity.PeopleEntity":{entity_type:[15,3,1,""],value:[15,3,1,""]},"dialogy.types.entity.time_entity":{TimeEntity:[15,2,1,""]},"dialogy.types.entity.time_entity.TimeEntity":{dim:[15,3,1,""],entity_type:[15,3,1,""],reshape:[15,4,1,""],value:[15,3,1,""]},"dialogy.types.entity.time_interval_entity":{TimeIntervalEntity:[15,2,1,""]},"dialogy.types.entity.time_interval_entity.TimeIntervalEntity":{dim:[15,3,1,""],entity_type:[15,3,1,""],origin:[15,3,1,""],reshape:[15,4,1,""],set_value:[15,4,1,""],value:[15,3,1,""]},"dialogy.types.intent":{Intent:[16,2,1,""]},"dialogy.types.intent.Intent":{add_parser:[16,4,1,""],apply:[16,4,1,""],cleanup:[16,4,1,""],fill_slot:[16,4,1,""],json:[16,4,1,""]},"dialogy.types.signal":{signal:[18,0,0,"-"]},"dialogy.types.slots":{Slot:[19,2,1,""]},"dialogy.types.slots.Slot":{add:[19,4,1,""],clear:[19,4,1,""],json:[19,4,1,""]},"dialogy.utils":{logger:[21,0,0,"-"],traverse_dict:[21,1,1,""],validate_type:[21,1,1,""]},"dialogy.utils.logger":{change_log_level:[21,1,1,""],debug_logs:[21,1,1,""]},"dialogy.workflow":{workflow:[22,0,0,"-"]},"dialogy.workflow.workflow":{Workflow:[22,2,1,""]},"dialogy.workflow.workflow.Workflow":{flush:[22,4,1,""],inference:[22,4,1,""],load_model:[22,4,1,""],postprocess:[22,4,1,""],preprocess:[22,4,1,""],run:[22,4,1,""],update:[22,4,1,""]},dialogy:{cli:[2,0,0,"-"],constants:[3,0,0,"-"],parser:[4,0,0,"-"],plugin:[7,0,0,"-"],postprocess:[8,0,0,"-"],preprocess:[12,0,0,"-"],types:[14,0,0,"-"],utils:[21,0,0,"-"],workflow:[22,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","attribute","Python attribute"],"4":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:attribute","4":"py:method"},terms:{"556a11057179":21,"639":[],"6th":15,"8000":[],"abstract":[7,22],"case":[7,11,13,15,16,22],"class":[0,3,7,10,11,15,16,19,21,22],"const":[13,15],"default":[2,11,13,15,22],"export":0,"final":22,"float":[11,13,15,16],"function":[2,7,11,13,15,16,21,22],"import":[0,3,10,11,13,15,16,17,19,20,21],"int":[11,15,16,21],"long":22,"new":[2,15],"return":[2,10,11,13,15,16,19,21,22],"static":7,"true":[10,11,13,16,21,22],"try":21,"while":[7,11,15],Its:15,LMs:13,Not:10,One:[21,22],That:13,The:[2,7,11,13,15,16,21,22],There:[14,16,21,22],These:[7,13,15,22],Use:[11,15,22],Uses:22,__call__:[],__init__:[2,7,21],__postprocessor:22,__preprocessor:22,__valid:15,_oos_:11,_plugin:7,abl:13,abort:2,about:11,accept:0,access:[7,10,11,13,15,17,21,22],across:[],act:14,action:[10,16,22],action_slot:10,adapt:13,add:[15,19],add_pars:[15,16],added:15,addit:[7,10],address:[13,15],adjust_signal_strength:11,advanc:22,affect:0,affirm:11,after:[0,15,22],against:22,aggreg:11,aggregate_fn:11,agnost:0,ahead:15,aim:22,air:14,algorithm:11,all:[1,11,13,15,19,21],allow:[10,11,22],alpha2:[],alreadi:[2,14],also:15,altern:[11,13,20],alternative_index:[10,15,16],analog:21,ani:[2,7,10,11,13,15,16,19,21,22],anomali:11,anoth:22,anticip:22,anyon:1,anyth:22,apart:22,api:7,appli:[7,13,15,16,21],applic:[0,22],arbitrari:[13,15,22],arg:[15,21,22],arg_nam:21,argument:[11,13,22],arrang:10,artifact:13,asia:[],ask:13,asr:[11,13],assert:21,assist:[10,13],associ:[10,14,16],assum:[7,22],assumpt:0,attempt:11,attr_nam:21,attribut:[15,16,21,22],audio:13,avail:[15,21],back:21,bad:22,base:[0,3,7,10,11,15,16,19,22],base_ent:[1,14,16,19],base_entity_prop:3,baseent:[10,15,16,19,22],battri:0,becaus:22,been:22,beep:21,befor:[13,22],being:[7,11,15,21],best:[11,13],better:7,between:[10,14,15,22],beyond:11,bit:10,bloat:15,block:22,bodi:[3,10,15,16],boilerpl:0,book:15,bool:[7,10,11,13,15,16,22],boost:11,booster:11,bop:21,both:15,box:7,briefli:21,build:[0,22],built:[7,11],bunch:22,bundl:22,call:[15,16,21],callabl:[7,10,11,13,15,16,21,22],can:[0,7,10,11,13,14,15,16,19,22],candid:11,care:22,categori:10,caution:[11,13,15],certain:[10,13],challeng:7,chanc:13,chang:[7,15,21,22],change_log_level:21,check:[10,13,15,16,21,22],children:15,choic:[0,22],classifi:[10,11,22],classmethod:15,cleanup:16,clear:19,cli:[0,1,23],cls:15,code:[0,13],collat:22,collect:[0,15],com:[10,13],command:2,common:13,compat:10,compli:15,complianc:15,compon:0,comput:22,concat:13,concaten:[11,13],conceal:15,concept:22,condit:[21,22],conduit:22,confid:11,configur:[10,13,16,21],connect:[],consensu:11,consid:[11,14],consider:[11,22],consist:[],constant:[0,1,23],constitu:11,constraint:22,contain:[10,11,15,16],content:[0,23],context:7,contextu:11,continu:11,conveni:[7,22],convent:7,convers:14,convert:[15,16,19],copi:[2,15],copier:2,core:22,corpu:7,corpus_dir:7,corpus_fil:7,cost:13,could:[11,22],count:11,count_peopl:10,counterpart:11,countri:[],coupl:[15,22],cover:[13,15],creat:[0,2,7,10,13,15,16],critic:21,currenc:[],current:[2,10,15,19,22],custom:7,customplugin:7,cuz:13,dai:15,dampen:11,data:[2,13,15],databas:[],dataset:2,date:[14,15],datetim:15,debug:[7,10,11,15,16,21,22],debug_log:21,decemb:15,decid:11,decor:21,deep:15,deepli:21,def:[7,11],defin:[10,11,13,15,17,22],definit:[13,16,19],demo:[16,22],denot:15,depend:[15,22],depict:11,deploi:[],deprec:6,describ:21,design:[7,10,11,22],desir:22,destin:14,destination_path:2,detail:[0,13,16],develop:13,dialog:10,dict:[10,13,15,16,19,21],dict_:15,dict_get:13,dict_travers:21,dictionari:[15,16,19,21],did:11,differ:[7,11,13,15,16],dim:[3,10,15],dimens:15,dir:2,directli:[7,22],directori:2,dissimilar:13,document:13,doe:10,doesn:[13,15,21],don:[7,21],down:[],downstream:13,drop:22,duckl:15,duckling_ent:[],duckling_pars:[4,5],duckling_plugin:[],ducklingpars:6,ducklingplug:6,ducklingplugin:[6,7,22],due:21,durat:[3,15],duration_ent:[1,14],durationent:15,dynam:7,each:[10,11,13,15],eas:11,easi:0,either:[14,15,21],elect:11,element:[10,13,15,21,22],els:[11,13],emit:11,en_gb:[],en_in:[],en_u:[],encourag:7,end:[3,7,10,13],enforc:22,english:10,entiti:[1,4,5,10,14,16,19,21,22],entity_synthesi:15,entity_typ:[10,15],entitykei:3,error:21,especi:[],etc:22,evalu:11,even:[7,10],everi:22,everyth:13,evid:11,exampl:[2,7,10,14,15],except:21,exclus:21,execut:[21,22],exhibit:[2,22],exist:[2,7,13,21],expect:[7,10,11,13,14,15,22],experi:[],explicitli:15,explor:16,expos:[2,7],express:[],extend:7,extern:7,extra:[],extract:[10,19],facilit:13,fact:13,fail:[11,13],fairli:22,fallback:11,fallback_int:11,fals:[7,10,11,13,15,16,22],faq:10,featur:7,few:[0,7,10,14,22],field:[],file:2,file_path:7,fill:[10,14,16,19,22],fill_multipl:[10,16],fill_slot:16,filler:10,filter:[11,15,22],find:11,fine:13,first:21,flag:21,flatten:13,flavor:15,flexibl:22,flight:15,flush:22,focu:0,follow:22,foreign:22,forest:11,fork:[],form:13,format:[10,13],found:10,framework:0,free:7,frequenc:11,from:[2,3,7,10,11,13,15,16,21,22],from_dict:15,func:21,gap:11,gener:[2,11,14],geographi:[],geopointent:15,get:[0,10,13,15,22],get_valu:15,getworkflowutterancefn:[13,17],github:13,given:[2,13,15,21],goe:11,good:1,grain:[3,15],graviti:22,great:13,ground:22,group:11,guid:[],had:11,hamper:7,handl:[7,10,11,13,15,22],hang:22,has:[7,11,15,16],have:[0,10,11,13,15,16,21,22],healthi:11,hello:[2,13],help:[0,2,7,11,13,15,16],here:[2,7,11,13,22],heurist:11,high:11,hold:16,hollow:22,hope:[7,13],how:11,html:10,http:[10,13],ideal:[7,11,22],ident:13,identifi:[10,15,16],ids:15,impact:13,imper:[],implement:[7,15,22],impli:[11,13,21],improv:[7,11,13],includ:[0,15],inconsequenti:13,index:[0,21],indexerror:[15,21],infer:22,info:21,inform:[11,13,15,18],inner:22,input:[7,10,11,13,15,21,22],input_:[7,10,11,13,21,22],insert:[7,19],instal:2,instanc:[7,11,15,16,19,21],instanti:[10,15],instead:[6,13,21],intend:15,intent:[1,10,11,14,22],intent_detection_slot_fil:10,intent_nam:10,intent_vot:[8,9],interact:[0,7,22],interfac:[],intermedi:11,interv:[3,15],invoc:2,invok:[],ipython:21,irrespect:10,is_each_el:13,is_list:13,is_list_of_str:13,is_str:13,is_unsqueezed_utter:13,is_utter:13,isn:[10,22],iso3166:[],iso:[],isol:7,issu:[13,15],item:10,iter:22,its:[7,10,11,15,16],join:[7,13],json:[15,16,19,22],judg:22,just:[7,13],keep:7,kei:[7,13,15,19],key_error:21,keyerror:[15,21],know:[13,22],known:15,kolkata:[],kwarg:21,lambda:[10,11,13,21],languag:[21,22],largest:22,last:21,latent:[3,10,15],latitud:15,lead:[11,21],learn:[0,11,22],leav:13,len:11,let:[0,10,11],level:[21,22],lib:13,librari:0,light:22,like:[7,10,11,13,14,15],line:2,link:2,lint:2,list:[10,11,13,15,16,19,21,22],littl:22,load:[7,22],load_corpu:7,load_model:22,local:[],locat:[2,15],location_ent:[1,14],locationent:[10,15],log:[11,21,22],logger:[1,23],logic:21,longitud:15,look:[10,11,13,22],machin:[0,22],made:[0,7,11],mai:[10,13,22],main:2,make:[0,2,13,15,21,22],manag:22,mani:[11,22],map:10,mar:21,mark:13,mastercard:13,match:[10,13,15,21],mayb:16,maybe_utter:13,mean:[11,14,16],meant:15,medium:22,merg:13,merge_asr_output:[1,12],merge_asr_output_plugin:[7,13],met:[7,11],meta:15,method:[7,10,15,21,22],metric:2,minim:0,mismatch:21,miss:[2,13,21],mock:[11,22],model:[2,10,11,13,22],modif:[7,15,16],modifi:[11,16,22],modul:[0,23],more:[10,11,13,15,22],most:[13,21],multipl:[11,13,16],must:[2,7,21],mutat:[7,10,11,13,15,22],naiv:11,name:[2,3,7,10,11,15,16,19,21,22],namespac:2,navig:21,neatli:22,necessari:15,need:[1,10,11,13,15,21],neg:11,neither:21,nest:21,new_project:2,nlp:13,nlpprogress:10,nois:13,non:13,none:[2,7,10,11,13,15,16,21,22],nonetyp:2,normal:[10,11,13,15],normalize_utter:[1,12],note:[],noth:[11,15],notic:[10,11,13],notimplementederror:22,now:11,number:[10,11,14,15,22],number_ent:10,number_slot:10,numer:15,numerical_ent:[1,14],numericalent:[10,15],obj:[13,21],obj_typ:21,object:[3,7,15,16,19,21,22],observ:11,obtain:[11,15],occurr:11,offer:[2,7,22],onc:[7,10],one:[10,11,14],ones:22,onli:[10,11,13,21],open:[7,15],oper:[13,15],opinion:0,option:[2,7,10,11,13,15,16,22],organ:2,origin:[3,10,14,15],other:[0,10,11,15,22],out:[10,11,13,16,21],output:[7,10,11,13,22],over:[11,22],overal:11,overrid:[15,22],overridden:[15,22],owing:13,own:15,packag:[0,23],page:0,paint:11,param:21,paramet:[2,10,11,13,15,16,21,22],pars:[13,15,21],parser:[0,1,10,15,16,23],part:[],parti:7,partial:13,particip:14,pass:[10,11,21,22],passeng:14,path:[7,21,22],pattern:[],peopl:[7,10,15],people_ent:[1,10,14],people_entity_prop:3,peopleent:[10,15],per:[7,10],percentag:11,perform:13,pertain:10,pick:11,pictur:11,pip:0,pipe:22,pipelin:[7,22],place:[7,11,13,22],plain:11,planet:21,pleas:6,plugin:[0,1,10,11,13,14,15,16,22,23],pluginfn:[7,10,11,15,16,17,22],poetri:2,point:[2,7,11],poor:11,popular:0,portabl:[7,22],posit:13,possibl:[16,21],post:[7,22],postprocess:[0,1,15,16,22,23],postprocessor:[3,10,11,15,16,22],pprint:10,practic:10,pre:[7,10,17,22],precis:13,predict:[11,22],prefer:[16,21],preprocess:[0,1,22,23],preprocessor:[3,10,11,22],present:10,preset:10,prevent:15,privat:[],problem:[0,13],procedur:22,process:[7,22],processor:22,processor_typ:22,produc:[11,13],product:[11,15,16],progress:[0,14,15,16],project:[1,3,14,21,22,23],prop:13,properti:[13,15,21],property_:15,proport:11,provid:[3,7,10,11,13,15,17,18,20,21],proxi:22,purpos:15,put:22,python:21,pytz:[],rais:[10,11,13,15,21,22],rang:[3,10,15,21],rank:11,reach:[],read:7,readi:[0,11],recal:13,receiv:[11,22],recent:21,recurs:21,reduc:[11,21],refer:[13,15],relai:22,relat:10,relationship:[10,14],remain:11,remov:[16,19],replac:15,report:10,repres:[10,13],represent:[3,11,15],requir:[7,13,14,22],reserv:14,reset:22,reshap:15,resid:13,resort:11,respect:[13,14,15],respons:13,restrict:[7,21,22],result:22,review:0,root:2,round:14,rtype:[15,21],rule:[10,16],rule_slot_fil:[8,9],rule_str:10,rulebasedslotfillerplugin:[7,10,16,22],ruleslotfilerplugin:7,run:[7,10,11,21,22],runtim:7,safe:[7,11,15],safe_load:10,safeguard:22,safest:11,sai:[11,22],said:15,same:[7,16],sauc:1,sauci:22,scaffold:[0,2],schema:10,score:[10,11,15,16],screen:2,search:0,second:15,section:[14,15],see:22,self:7,semant:13,sentenc:[13,14,15],sentence2vecplugin:7,separ:[7,13],server:[],servic:[],session:0,set:[7,10,11,14,15,16,21],set_valu:15,shall:10,share:16,shift:22,ship:[7,13],should:[10,11,13,15,16,22],show:2,sic:22,signal:[1,3,11,14],signatur:[10,22],signific:[10,13,14],similar:[11,13,22],simpl:[0,2,7,13,22],simpli:13,simul:11,sinc:[6,7,11,13],singl:[10,11,13,16],situat:11,size:11,skip:15,skip_entity_attr:15,slot:[1,10,11,14,16,22],slot_fil:[8,9],slot_nam:[3,10,15],slot_rul:10,slot_typ:16,slow:[],slu:[0,11,14,22],smallest:15,solut:[0,7],some:[7,11,13,15,22],somewher:[],sort:22,sourc:[2,3,7,10,11,13,15,16,19,21,22],sparingli:21,speaker:21,special:[1,16],specif:[15,21],specifi:[2,7],speech:0,splitlin:7,stack:0,stage:7,stall:[],standard:13,start:[2,3,10,13],state:[11,13],statist:22,str:[2,7,10,11,13,15,16,19,21,22],strategi:13,strength:[3,11],string:[11,13],strong:11,stronger:22,structur:[7,13,15,22],sub:[0,22],subclass:[15,22],submodul:[1,4,5,8,9,12,14,23],subpackag:[0,23],sugar:[15,21],summar:7,supplier:22,support:[2,13,15,16,22],suppos:[15,22],sure:[],syntact:[],syntat:21,synthet:10,system:[10,13],tailor:7,take:[11,22],task:[13,22],tell:[10,11,14,15],templat:[0,2],tend:13,termin:13,text:[1,4,8,12,16],than:[10,11],thei:[13,22],them:[7,10,13,21],therefor:7,thi:[2,7,10,11,13,14,15,16,18,19,21,22],think:22,third:[7,10],those:[15,21,22],though:13,threshold:11,through:[10,15,22],throughout:[7,21],throughtout:3,thud:22,ticket:14,time:[10,14,15,21],time_ent:[1,14],time_entity_prop:3,time_interval_ent:[1,14],time_slot:10,timeent:[10,15],timeinterv:[],timeintervalent:15,timeout:[],timestamp:15,timezon:[],todai:15,token:[10,11,14,15],top:11,total:11,traceback:21,transcript:[11,13],transform:[0,2,13],travel:14,travers:21,traverse_dict:21,tree:11,trial:11,trip:14,triplet:15,tupl:[10,11,21],two:[10,11,15,21,22],type:[0,1,2,3,10,11,13,21,22,23],type_:13,typeerror:[10,11,13,21,22],umm:13,unawar:7,under:[11,13],understand:16,union:[13,21],uniqu:[11,13],unit:[3,10,15],unk:11,unless:10,unsaf:[11,15],unset:13,updat:[7,10,15,16,21,22],update_int:11,update_workflow:[],updateworkflowstringfn:[13,17],upon:14,url:[],usag:[2,7],use:[0,2,6,7,10,13,14,22],used:[3,13,15,21,22],useful:[7,21],user:2,uses:2,using:[0,2,11,15,16,21,22],usual:7,util:[0,1,2,10,11,15,16,23],utter:[1,13,14,15],valid:15,validate_typ:21,valu:[3,7,10,11,13,15,16,19,21,22],variant:15,variou:[7,13],vector:13,veri:[11,13,22],verifi:15,vernacular:[2,13],version:[2,6,22],vertic:22,via:[7,21],vote:[8,9],vote_plugin:11,vote_sign:11,voteintentplugin:11,voteplugin:[7,11,13,22],wai:[7,11,14,21],want:[13,15,16,22],warn:21,weak:11,weight:11,well:[13,22],were:[15,16,22],when:[],where:[1,2,11,13,15,16],which:[11,13,15,16,22],whole:15,why:1,win:11,wish:15,within:[13,14,15,16,19,21,22],without:[21,22],won:[7,22],words2num_plugin:7,work:[13,14,22],workflow:[0,1,7,10,11,13,23],workflow_public_properti:3,world:[2,13],worri:22,worst:11,would:[1,13,14],wrap:21,wrapper:21,write:[0,7],written:7,yaml:10,yep:11,yes:[11,22],yet:11,yield:11,you:[0,10,13,14,22],your:[0,22],your_project_nam:0},titles:["Welcome to dialogy\u2019s documentation!","dialogy package","dialogy.cli package","dialogy.constants package","dialogy.parser package","dialogy.parser.text package","dialogy.parser.text.entity package","dialogy.plugin package","dialogy.postprocess package","dialogy.postprocess.text package","dialogy.postprocess.text.slot_filler package","dialogy.postprocess.text.voting package","dialogy.preprocess package","dialogy.preprocess.text package","dialogy.types package","dialogy.types.entity package","dialogy.types.intent package","dialogy.types.plugin package","dialogy.types.signal package","dialogy.types.slots package","dialogy.types.utterances package","dialogy.utils package","dialogy.workflow package","dialogy"],titleterms:{all:22,anyon:22,base_ent:15,cli:2,constant:3,content:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22],dialogi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],document:0,duckling_pars:6,duration_ent:15,entiti:[6,15],faq:0,good:22,indic:0,instal:0,intent:16,intent_vot:11,location_ent:15,logger:21,merge_asr_output:13,modul:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22],need:22,normalize_utter:13,numerical_ent:15,packag:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22],parser:[4,5,6],people_ent:15,plugin:[7,17],postprocess:[8,9,10,11],preprocess:[12,13],project:[0,2],rule_slot_fil:10,sauc:22,signal:18,slot:19,slot_fil:10,special:22,start:0,submodul:[2,6,7,10,11,13,15,18,21,22],subpackag:[1,4,5,8,9,12,14],tabl:0,test:0,text:[5,6,9,10,11,13],time_ent:15,time_interval_ent:15,type:[14,15,16,17,18,19,20],util:21,utter:20,vote:11,welcom:0,where:22,why:22,workflow:22,would:22}})
\ No newline at end of file
diff --git a/docs/source/dialogy.parser.text.entity.html b/docs/source/dialogy.parser.text.entity.html
index 312ab8f7..e276cab4 100644
--- a/docs/source/dialogy.parser.text.entity.html
+++ b/docs/source/dialogy.parser.text.entity.html
@@ -171,145 +171,9 @@ <h2>Submodules<a class="headerlink" href="#submodules" title="Permalink to this
 </section>
 <section id="module-dialogy.parser.text.entity.duckling_parser">
 <span id="dialogy-parser-text-entity-duckling-parser-module"></span><h2>dialogy.parser.text.entity.duckling_parser module<a class="headerlink" href="#module-dialogy.parser.text.entity.duckling_parser" title="Permalink to this headline">¶</a></h2>
-<p id="duckling-parser">This module exposes a parser for <a class="reference external" href="https://github.com/facebook/duckling">Duckling</a>.</p>
-<p><a class="reference external" href="https://github.com/facebook/duckling">Duckling</a> helps parsing values like: <code class="code docutils literal notranslate"><span class="pre">date</span></code>, <code class="code docutils literal notranslate"><span class="pre">time</span></code>,
-<code class="code docutils literal notranslate"><span class="pre">numbers</span></code>, <code class="code docutils literal notranslate"><span class="pre">currency</span></code> etc. The parser will expect Duckling to be running as an http service, and provide
-means to connect from the implementation here.</p>
-<div class="highlight-python notranslate"><div class="table-wrapper"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">dialogy.workflow</span> <span class="kn">import</span> <span class="n">Workflow</span>
-
-<span class="k">def</span> <span class="nf">update_workflow</span><span class="p">(</span><span class="n">workflow</span><span class="p">,</span> <span class="n">entities</span><span class="p">):</span>
-<span class="hll">    <span class="n">workflow</span><span class="o">.</span><span class="n">input</span><span class="p">[</span><span class="s2">"duckling_entities"</span><span class="p">]</span> <span class="o">=</span> <span class="n">entities</span>
-</span>
-<span class="n">duckling_plugin</span> <span class="o">=</span> <span class="n">DucklingParser</span><span class="p">(</span>
-    <span class="n">access</span><span class="o">=</span><span class="k">lambda</span> <span class="n">workflow</span><span class="p">:</span> <span class="n">workflow</span><span class="o">.</span><span class="n">input</span><span class="p">[</span><span class="s2">"sentence"</span><span class="p">],</span>
-    <span class="c1"># the access method guides the plugin to data within a workflow.</span>
-    <span class="c1"># in this case, the `input` property of a workflow is expected</span>
-    <span class="c1"># to be a `dict` with a key named "sentence". Check line 30.</span>
-    <span class="n">mutate</span><span class="o">=</span><span class="n">update_workflow</span><span class="p">,</span>
-    <span class="c1"># the mutate method guides the plugin to place the processed output</span>
-    <span class="c1"># somewhere on the workflow.</span>
-    <span class="n">dimensions</span><span class="o">=</span><span class="p">[</span><span class="s2">"people"</span><span class="p">],</span>
-    <span class="c1"># Duckling supports multiple dimensions, by specifying a list, we make sure</span>
-    <span class="c1"># we are searching for a match within the expected dimensions only.</span>
-    <span class="n">locale</span><span class="o">=</span><span class="s2">"en_IN"</span><span class="p">,</span>
-    <span class="c1"># Duckling supports a set of locales, we need to provide this info to</span>
-    <span class="c1"># get language specific matches.</span>
-    <span class="n">timezone</span><span class="o">=</span><span class="s2">"Asia/Kolkata"</span><span class="p">,</span>
-    <span class="c1"># Date/Time related entities make this field imperative.</span>
-<span class="p">)()</span> <span class="c1"># ⬅️ the instance is also getting called.</span>
-<span class="c1"># Notice that we instantiate the class and also</span>
-<span class="c1"># invoke __call__ method of the instance.</span>
-<span class="c1"># The returned value from the instance is the plugin.</span>
-<span class="c1">#</span>
-<span class="c1"># This is a standard pattern across all plugins.</span>
-
-<span class="n">workflow</span> <span class="o">=</span> <span class="n">Workflow</span><span class="p">(</span><span class="n">preprocessors</span><span class="o">=</span><span class="p">[</span><span class="n">duckling_plugin</span><span class="p">])</span>
-<span class="hll"><span class="n">workflow</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">input_</span><span class="o">=</span><span class="p">{</span><span class="s2">"sentence"</span><span class="p">:</span> <span class="s2">"there are 7 people"</span><span class="p">})</span>
-</span><span class="c1"># Once an input is run through the workflow as on line 30,</span>
-<span class="c1"># we can expect the plugin mutation to create an artifact</span>
-<span class="c1"># as per line 4.</span>
-</pre></div>
-</td></tr></table></div></div>
-<dl class="py class">
-<dt id="dialogy.parser.text.entity.duckling_parser.DucklingParser">
-<em class="property"><span class="pre">class</span> </em><code class="sig-prename descclassname"><span class="pre">dialogy.parser.text.entity.duckling_parser.</span></code><code class="sig-name descname"><span class="pre">DucklingParser</span></code><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dimensions</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span></span></em>, <em class="sig-param"><span class="n"><span class="pre">locale</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timezone</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">float</span></span> <span class="o"><span class="pre">=</span></span> <span class="default_value"><span class="pre">0.5</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">url</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">str</span></span> <span class="o"><span class="pre">=</span></span> <span class="default_value"><span class="pre">'http://0.0.0.0:8000/parse'</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">access</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">Optional</span><span class="p"><span class="pre">[</span></span><span class="pre">Callable</span><span class="p"><span class="pre">[</span></span><span class="p"><span class="pre">[</span></span><span class="p"><span class="pre">…</span></span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">,</span> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span> <span class="o"><span class="pre">=</span></span> <span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">mutate</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">Optional</span><span class="p"><span class="pre">[</span></span><span class="pre">Callable</span><span class="p"><span class="pre">[</span></span><span class="p"><span class="pre">[</span></span><span class="p"><span class="pre">…</span></span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">,</span> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span> <span class="o"><span class="pre">=</span></span> <span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">debug</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">bool</span></span> <span class="o"><span class="pre">=</span></span> <span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/dialogy/parser/text/entity/duckling_parser.html#DucklingParser"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#dialogy.parser.text.entity.duckling_parser.DucklingParser" title="Permalink to this definition">¶</a></dt>
-<dd><p>Bases: <a class="reference internal" href="dialogy.plugin.html#dialogy.plugin.plugin.Plugin" title="dialogy.plugin.plugin.Plugin"><code class="xref py py-class docutils literal notranslate"><span class="pre">dialogy.plugin.plugin.Plugin</span></code></a></p>
-<p>A <a class="reference internal" href="dialogy.plugin.html#plugin"><span class="std std-ref">Plugin</span></a> for extracting entities using <a class="reference external" href="https://github.com/facebook/duckling">Duckling</a>. Once
-instantiated, a <code class="code docutils literal notranslate"><span class="pre">duckling_parser</span></code> object will interface to an http server, running <a class="reference external" href="https://github.com/facebook/duckling">Duckling</a>.</p>
-<p>This object when used as a plugin, transforms the <code class="code docutils literal notranslate"><span class="pre">List[Dict[str,</span> <span class="pre">Any]]</span></code> returned from the API to a
-<a class="reference internal" href="dialogy.types.entity.html#base-entity"><span class="std std-ref">BaseEntity</span></a> or one of its subclasses.</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><p><strong>dimensions</strong> – <a class="reference external" href="https://github.com/facebook/duckling#supported-dimensions">Dimensions</a>. Of the listed</p>
-</dd>
-</dl>
-<p>dimensions, we support:</p>
-<blockquote>
-<div><ul class="simple">
-<li><p><cite>Numeral</cite></p></li>
-<li><p><cite>Time</cite></p></li>
-<li><p><cite>TimeInterval</cite></p></li>
-<li><p><cite>Duration</cite></p></li>
-<li><p><cite>People</cite> - This isn’t part of the standard, we have a private fork to support this.</p></li>
-</ul>
-<p>Do note, passing more dimensions is not free. Duckling would search for extra set of patterns just because
-those dimensions were expected.</p>
-</div></blockquote>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><ul class="simple">
-<li><p><strong>locale</strong> (<em>str</em>) – The format for expressing locale requires language code and country name ids. Read about
-<a class="reference external" href="https://github.com/facebook/duckling#extending-duckling">sections</a> that define
-<a class="reference external" href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes">ISO-639-codes</a> for languages and
-<a class="reference external" href="https://www.iso.org/obp/ui/#search/code/">ISO3166 alpha2 country code</a> for country codes.
-Examples: <cite>“en_IN”</cite>, <cite>“en_US”</cite>, <cite>“en_GB”</cite>.</p></li>
-<li><p><strong>timezone</strong> – <cite>pytz</cite> Timezone. This is especially important when services are deployed across different</p></li>
-</ul>
-</dd>
-</dl>
-<p>geographies and consistency is expected in the responses. Get a valid value from a <a class="reference external" href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">list of tz database timezones</a>. Example: <cite>“Asia/Kolkata”</cite> :type timezone:
-Optional[str]</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><p><strong>timeout</strong> – There are certain strings which tend to stall Duckling:</p>
-</dd>
-</dl>
-<p><a class="reference external" href="https://github.com/facebook/duckling/issues/338">example</a>.
-In such cases, to prevent the overall experience to slow
-down as well, provide a certain timeout value, defaults to 0.5.
-:type timeout: float</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><p><strong>url</strong> (<em>Optional</em><em>[</em><em>str</em><em>]</em>) – The address where Duckling’s entity parser can be reached, defaults to “<a class="reference external" href="http://0.0.0.0:8000/parse">http://0.0.0.0:8000/parse</a>”.</p>
-</dd>
-</dl>
-<dl class="py method">
-<dt id="dialogy.parser.text.entity.duckling_parser.DucklingParser.plugin">
-<code class="sig-name descname"><span class="pre">plugin</span></code><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">workflow</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><a class="reference internal" href="dialogy.workflow.html#dialogy.workflow.workflow.Workflow" title="dialogy.workflow.workflow.Workflow"><span class="pre">dialogy.workflow.workflow.Workflow</span></a></span></em><span class="sig-paren">)</span> → <span class="pre">None</span><a class="reference internal" href="../_modules/dialogy/parser/text/entity/duckling_parser.html#DucklingParser.plugin"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#dialogy.parser.text.entity.duckling_parser.DucklingParser.plugin" title="Permalink to this definition">¶</a></dt>
-<dd><p>Insert a list of <a class="reference internal" href="dialogy.types.entity.html#base-entity"><span class="std std-ref">BaseEntity</span></a> objects into the Workflow.</p>
-<p>This function is also available through the __call__ method as syntactic sugar.</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><p><strong>workflow</strong> – A <a class="reference internal" href="dialogy.workflow.html#workflow"><span class="std std-ref">Workflow</span></a> on which the plugin should operate.</p>
-</dd>
-<dt class="field-even">Returns</dt>
-<dd class="field-even"><p></p>
-</dd>
-</dl>
-</dd></dl>
-</dd></dl>
+<div class="deprecated">
+<p><span class="versionmodified deprecated">Deprecated since version DucklingParser: </span>will be deprecated, please use DucklingPlugin instead. Please use DucklingPlug</p>
+</div>
 </section>
 <section id="module-dialogy.parser.text.entity">
 <span id="module-contents"></span><h2>Module contents<a class="headerlink" href="#module-dialogy.parser.text.entity" title="Permalink to this headline">¶</a></h2>
diff --git a/docs/source/dialogy.plugin.html b/docs/source/dialogy.plugin.html
index 0fa2fd01..4d9b201b 100644
--- a/docs/source/dialogy.plugin.html
+++ b/docs/source/dialogy.plugin.html
@@ -243,7 +243,7 @@ <h2>Submodules<a class="headerlink" href="#submodules" title="Permalink to this
 </td></tr></table></div></div>
 <p>We ship a few <a class="reference internal" href="#plugin"><span class="std std-ref">Plugins</span></a> with Dialogy, namely:</p>
 <ol class="arabic simple">
-<li><p><a class="reference internal" href="dialogy.parser.text.entity.html#duckling-parser"><span class="std std-ref">DucklingParser</span></a> (pre-processing)</p></li>
+<li><p><span class="xref std std-ref">DucklingPlugin</span> (pre-processing)</p></li>
 <li><p><a class="reference internal" href="dialogy.preprocess.text.html#merge-asr-output-plugin"><span class="std std-ref">merge_asr_output_plugin</span></a> (pre-processing)</p></li>
 <li><p><a class="reference internal" href="dialogy.postprocess.text.slot_filler.html#rule-slot-filler"><span class="std std-ref">RuleBasedSlotFillerPlugin</span></a> (post-processing)</p></li>
 <li><p><a class="reference internal" href="dialogy.postprocess.text.voting.html#vote-plugin"><span class="std std-ref">VotePlugin</span></a> (post-processing)</p></li>
diff --git a/docs/source/dialogy.preprocess.text.html b/docs/source/dialogy.preprocess.text.html
index eb80ebda..1d12236f 100644
--- a/docs/source/dialogy.preprocess.text.html
+++ b/docs/source/dialogy.preprocess.text.html
@@ -308,13 +308,13 @@ <h2>Submodules<a class="headerlink" href="#submodules" title="Permalink to this
 <dl class="py function">
 <dt id="dialogy.preprocess.text.normalize_utterance.is_list">
 <code class="sig-prename descclassname"><span class="pre">dialogy.preprocess.text.normalize_utterance.</span></code><code class="sig-name descname"><span class="pre">is_list</span></code><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">input_</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">Any</span></span></em><span class="sig-paren">)</span> → <span class="pre">bool</span><a class="reference internal" href="../_modules/dialogy/preprocess/text/normalize_utterance.html#is_list"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#dialogy.preprocess.text.normalize_utterance.is_list" title="Permalink to this definition">¶</a></dt>
-<dd><p>Check type of <cite>input_</cite></p>
+<dd><p>Check type of <code class="code docutils literal notranslate"><span class="pre">input</span></code></p>
 <dl class="field-list simple">
 <dt class="field-odd">Parameters</dt>
 <dd class="field-odd"><p><strong>input</strong> (<em>Any</em>) – Any arbitrary input</p>
 </dd>
 <dt class="field-even">Returns</dt>
-<dd class="field-even"><p>True if <a href="#id1"><span class="problematic" id="id2">input_</span></a> is a <code class="code docutils literal notranslate"><span class="pre">list</span></code> else False</p>
+<dd class="field-even"><p>True if <code class="code docutils literal notranslate"><span class="pre">input</span></code> is a <code class="code docutils literal notranslate"><span class="pre">list</span></code> else False</p>
 </dd>
 <dt class="field-odd">Return type</dt>
 <dd class="field-odd"><p>True</p>
@@ -392,10 +392,7 @@ <h2>Submodules<a class="headerlink" href="#submodules" title="Permalink to this
 <dl class="py function">
 <dt id="dialogy.preprocess.text.normalize_utterance.is_utterance">
 <code class="sig-prename descclassname"><span class="pre">dialogy.preprocess.text.normalize_utterance.</span></code><code class="sig-name descname"><span class="pre">is_utterance</span></code><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">maybe_utterance</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">Any</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">key</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">str</span></span> <span class="o"><span class="pre">=</span></span> <span class="default_value"><span class="pre">'transcript'</span></span></em><span class="sig-paren">)</span> → <span class="pre">bool</span><a class="reference internal" href="../_modules/dialogy/preprocess/text/normalize_utterance.html#is_utterance"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#dialogy.preprocess.text.normalize_utterance.is_utterance" title="Permalink to this definition">¶</a></dt>
-<dd><p>Check input to be of <cite>List[List[Dict]]</cite>.</p>
-<p><code class="docutils literal notranslate"><span class="pre">`json</span>
-<span class="pre">[[{"transcript":</span> <span class="pre">"hi"}]]</span>
-<span class="pre">`</span></code></p>
+<dd><p id="is-utterance">Check input to be of <cite>List[List[Dict]]</cite>.</p>
 <div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [1]: </span><span class="kn">from</span> <span class="nn">dialogy.preprocess.text.normalize_utterance</span> <span class="kn">import</span> <span class="n">is_utterance</span>
 
 <span class="go"># 1. :code:`List[List[Dict[str, str]]]`</span>
diff --git a/docs/source/dialogy.types.entity.html b/docs/source/dialogy.types.entity.html
index 53dd4088..24ea5bfa 100644
--- a/docs/source/dialogy.types.entity.html
+++ b/docs/source/dialogy.types.entity.html
@@ -278,6 +278,12 @@ <h2>Submodules<a class="headerlink" href="#submodules" title="Permalink to this
 </dl>
 </dd></dl>
 <dl class="py method">
+<dt id="dialogy.types.entity.base_entity.BaseEntity.reshape">
+<em class="property"><span class="pre">classmethod</span> </em><code class="sig-name descname"><span class="pre">reshape</span></code><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dict_</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span> → <span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span><a class="reference internal" href="../_modules/dialogy/types/entity/base_entity.html#BaseEntity.reshape"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#dialogy.types.entity.base_entity.BaseEntity.reshape" title="Permalink to this definition">¶</a></dt>
+<dd><dl class="field-list simple">
+</dl>
+</dd></dl>
+<dl class="py method">
 <dt id="dialogy.types.entity.base_entity.BaseEntity.set_value">
 <code class="sig-name descname"><span class="pre">set_value</span></code><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">value</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">Optional</span><span class="p"><span class="pre">[</span></span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span></span> <span class="o"><span class="pre">=</span></span> <span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span> → <span class="pre">None</span><a class="reference internal" href="../_modules/dialogy/types/entity/base_entity.html#BaseEntity.set_value"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#dialogy.types.entity.base_entity.BaseEntity.set_value" title="Permalink to this definition">¶</a></dt>
 <dd><p>Set values and value attribute.</p>
@@ -486,6 +492,12 @@ <h2>Submodules<a class="headerlink" href="#submodules" title="Permalink to this
 <dt id="dialogy.types.entity.time_entity.TimeEntity.entity_type">
 <code class="sig-name descname"><span class="pre">entity_type</span></code><em class="property"><span class="pre">:</span> <span class="pre">Optional</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span></em><a class="headerlink" href="#dialogy.types.entity.time_entity.TimeEntity.entity_type" title="Permalink to this definition">¶</a></dt>
 <dd></dd></dl>
+<dl class="py method">
+<dt id="dialogy.types.entity.time_entity.TimeEntity.reshape">
+<em class="property"><span class="pre">classmethod</span> </em><code class="sig-name descname"><span class="pre">reshape</span></code><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dict_</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span> → <span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span><a class="reference internal" href="../_modules/dialogy/types/entity/time_entity.html#TimeEntity.reshape"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#dialogy.types.entity.time_entity.TimeEntity.reshape" title="Permalink to this definition">¶</a></dt>
+<dd><dl class="field-list simple">
+</dl>
+</dd></dl>
 <dl class="py attribute">
 <dt id="dialogy.types.entity.time_entity.TimeEntity.value">
 <code class="sig-name descname"><span class="pre">value</span></code><em class="property"><span class="pre">:</span> <span class="pre">Any</span></em><a class="headerlink" href="#dialogy.types.entity.time_entity.TimeEntity.value" title="Permalink to this definition">¶</a></dt>
@@ -526,6 +538,12 @@ <h2>Submodules<a class="headerlink" href="#submodules" title="Permalink to this
 <code class="sig-name descname"><span class="pre">origin</span></code><em class="property"> <span class="pre">=</span> <span class="pre">'interval'</span></em><a class="headerlink" href="#dialogy.types.entity.time_interval_entity.TimeIntervalEntity.origin" title="Permalink to this definition">¶</a></dt>
 <dd></dd></dl>
 <dl class="py method">
+<dt id="dialogy.types.entity.time_interval_entity.TimeIntervalEntity.reshape">
+<em class="property"><span class="pre">classmethod</span> </em><code class="sig-name descname"><span class="pre">reshape</span></code><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dict_</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span> → <span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span><a class="reference internal" href="../_modules/dialogy/types/entity/time_interval_entity.html#TimeIntervalEntity.reshape"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#dialogy.types.entity.time_interval_entity.TimeIntervalEntity.reshape" title="Permalink to this definition">¶</a></dt>
+<dd><dl class="field-list simple">
+</dl>
+</dd></dl>
+<dl class="py method">
 <dt id="dialogy.types.entity.time_interval_entity.TimeIntervalEntity.set_value">
 <code class="sig-name descname"><span class="pre">set_value</span></code><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">value</span></span><span class="p"><span class="pre">:</span></span> <span class="n"><span class="pre">Optional</span><span class="p"><span class="pre">[</span></span><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span> <span class="o"><span class="pre">=</span></span> <span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span> → <span class="pre">None</span><a class="reference internal" href="../_modules/dialogy/types/entity/time_interval_entity.html#TimeIntervalEntity.set_value"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#dialogy.types.entity.time_interval_entity.TimeIntervalEntity.set_value" title="Permalink to this definition">¶</a></dt>
 <dd><p>Set values and value attribute.</p>
diff --git a/docs/source/dialogy.workflow.html b/docs/source/dialogy.workflow.html
index e95c5abb..8e7206d9 100644
--- a/docs/source/dialogy.workflow.html
+++ b/docs/source/dialogy.workflow.html
@@ -199,7 +199,7 @@ <h3>Where’s the sauce?<a class="headerlink" href="#where-s-the-sauce" title="P
 an <code class="code docutils literal notranslate"><span class="pre">access</span></code> function (an argument to every <a class="reference internal" href="dialogy.plugin.html#plugin"><span class="std std-ref">Plugin</span></a>) and relays output through a <code class="code docutils literal notranslate"><span class="pre">mutate</span></code>
 function (another argument for every <a class="reference internal" href="dialogy.plugin.html#plugin"><span class="std std-ref">Plugin</span></a>). These two functions define interactions between many many
 (sic) <a class="reference internal" href="dialogy.plugin.html#plugin"><span class="std std-ref">Plugins</span></a> without knowing the inner workings of a <a class="reference internal" href="#workflow"><span class="std std-ref">Workflow</span></a>.</p>
-<p>Take a look at <span class="xref std std-ref">DucklingParser</span>, this plugin handles inputs, manages the default <code class="code docutils literal notranslate"><span class="pre">json</span></code> output
+<p>Take a look at <span class="xref std std-ref">DucklingPlugin</span>, this plugin handles inputs, manages the default <code class="code docutils literal notranslate"><span class="pre">json</span></code> output
 into neatly bundled <a class="reference internal" href="dialogy.types.entity.html#base-entity"><span class="std std-ref">BaseEntity</span></a> and other similar classes. Another plugin
 <a class="reference internal" href="dialogy.postprocess.text.slot_filler.html#rule-slot-filler"><span class="std std-ref">RuleBasedSlotFillerPlugin</span></a> takes care of slot names and the entity types that should be filled
 within.</p>


Test patch:
diff --git a/tests/parser/__init__.py b/tests/parser/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/tests/parser/text/__init__.py b/tests/parser/text/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/tests/parser/text/entity/__init__.py b/tests/parser/text/entity/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/tests/parser/text/entity/config.py b/tests/parser/text/entity/config.py
deleted file mode 100644
index 3967c26e..00000000
--- a/tests/parser/text/entity/config.py
+++ /dev/null
@@ -1,224 +0,0 @@
-mock_number_entity = {
-    "body": "four",
-    "start": 7,
-    "value": {"value": 4, "type": "value"},
-    "end": 11,
-    "dim": "number",
-    "latent": False,
-}
-
-mock_date_entity = {
-    "body": "on 27th next month",
-    "start": 21,
-    "value": {
-        "values": [
-            {
-                "value": "2021-01-27T00:00:00.000-08:00",
-                "grain": "day",
-                "type": "value",
-            }
-        ],
-        "value": "2021-01-27T00:00:00.000-08:00",
-        "grain": "day",
-        "type": "value",
-    },
-    "end": 39,
-    "dim": "time",
-    "latent": False,
-}
-
-mock_time_entity = {
-    "body": "at 5 am",
-    "start": 55,
-    "value": {
-        "values": [
-            {
-                "value": "2020-12-24T05:00:00.000-08:00",
-                "grain": "hour",
-                "type": "value",
-            },
-            {
-                "value": "2020-12-25T05:00:00.000-08:00",
-                "grain": "hour",
-                "type": "value",
-            },
-            {
-                "value": "2020-12-26T05:00:00.000-08:00",
-                "grain": "hour",
-                "type": "value",
-            },
-        ],
-        "value": "2020-12-24T05:00:00.000-08:00",
-        "grain": "hour",
-        "type": "value",
-    },
-    "end": 62,
-    "dim": "time",
-    "latent": False,
-}
-
-mock_interval_entity = {
-    "body": "between 2 to 4 am",
-    "start": 0,
-    "value": {
-        "values": [
-            {
-                "to": {
-                    "value": "2021-01-22T05:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "from": {
-                    "value": "2021-01-22T02:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-            {
-                "to": {
-                    "value": "2021-01-23T05:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "from": {
-                    "value": "2021-01-23T02:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-            {
-                "to": {
-                    "value": "2021-01-24T05:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "from": {
-                    "value": "2021-01-24T02:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-        ],
-        "to": {"value": "2021-01-22T05:00:00.000+05:30", "grain": "hour"},
-        "from": {"value": "2021-01-22T02:00:00.000+05:30", "grain": "hour"},
-        "type": "interval",
-    },
-    "end": 17,
-    "dim": "time",
-    "latent": False,
-}
-
-mock_interval_entity_from = {
-    "body": "from 2 am",
-    "start": 0,
-    "value": {
-        "values": [
-            {
-                "from": {
-                    "value": "2021-01-22T02:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-            {
-                "from": {
-                    "value": "2021-01-23T02:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-            {
-                "from": {
-                    "value": "2021-01-24T02:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-        ],
-        "from": {"value": "2021-01-22T02:00:00.000+05:30", "grain": "hour"},
-        "type": "interval",
-    },
-    "end": 9,
-    "dim": "time",
-    "latent": False,
-    "range": {"start": 0, "end": 9},
-    "type": "time",
-    "values": [
-        {
-            "from": {"value": "2021-01-22T02:00:00.000+05:30", "grain": "hour"},
-            "type": "interval",
-        }
-    ],
-}
-
-mock_interval_entity_to = {
-    "body": "to 4 am",
-    "start": 0,
-    "value": {
-        "values": [
-            {
-                "to": {
-                    "value": "2021-01-22T05:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-            {
-                "to": {
-                    "value": "2021-01-23T05:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-            {
-                "to": {
-                    "value": "2021-01-24T05:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-        ],
-        "to": {"value": "2021-01-22T05:00:00.000+05:30", "grain": "hour"},
-        "type": "interval",
-    },
-    "end": 7,
-    "dim": "time",
-    "latent": False,
-}
-
-mock_bad_interval_entity = {
-    "body": "between 2 am to 4 am",
-    "start": 0,
-    "value": {
-        "values": [
-            {
-                "type": "interval",
-            },
-            {
-                "type": "interval",
-            },
-            {
-                "type": "interval",
-            },
-        ],
-        "type": "interval",
-    },
-    "end": 17,
-    "dim": "time",
-    "latent": False,
-}
-
-mock_people_entity = {
-    "body": "3 people",
-    "start": 67,
-    "value": {"value": 3, "type": "value", "unit": "person"},
-    "end": 75,
-    "dim": "people",
-    "latent": False,
-}
-
-mock_unknown_entity = {
-    "body": "3 foobars",
-    "start": 67,
-    "value": {"value": 3, "type": "foobar", "unit": "person"},
-    "end": 75,
-    "dim": "number",
-    "latent": False,
-}
diff --git a/tests/parser/text/entity/test_duckling_parser.py b/tests/parser/text/entity/test_duckling_parser.py
deleted file mode 100644
index 8a53e625..00000000
--- a/tests/parser/text/entity/test_duckling_parser.py
+++ /dev/null
@@ -1,614 +0,0 @@
-import json
-from typing import Any, Callable, List
-
-import httpretty
-import pytest
-import pytz
-
-from dialogy.parser.text.entity import DucklingParser
-from dialogy.types.entity import (
-    DurationEntity,
-    NumericalEntity,
-    PeopleEntity,
-    TimeEntity,
-    TimeIntervalEntity,
-)
-from dialogy.workflow import Workflow
-from tests.parser.text.entity import config
-
-
-def request_builder(
-    expected_response, response_code=200
-) -> Callable[[Any, Any, Any], List[Any]]:
-    header = "application/x-www-form-urlencoded; charset=UTF-8"
-
-    def request_callback(request, _, response_headers) -> List[Any]:
-        content_type = request.headers.get("Content-Type")
-        assert (
-            content_type == header
-        ), f"expected {header} but received Content-Type: {content_type}"
-        return [response_code, response_headers, json.dumps(expected_response)]
-
-    return request_callback
-
-
-# == Test successful api call ==
-@httpretty.activate
-def test_duckling_api_success() -> None:
-    """
-    Initialize DucklingParser and `.get_entities`.
-
-    This test-case bypasses duckling API calls via httpretty. The expected response
-    was originally generated using:
-
-    ```shell
-
-    export month_q="I need four of those on 27th next month."
-    export time_q="Can I have it at 5 am""&dims="[date"]"
-    export text="$month_q $time_q"
-    curl -XPOST http://0.0.0.0:8000/parse --data 'locale=en_US&text=$text'
-    ```
-    """
-    body = "I need four of those on 27th next month. Can I have it at 5 am"
-
-    expected_response = [
-        config.mock_number_entity,
-        config.mock_date_entity,
-        config.mock_time_entity,
-    ]
-
-    request_callback = request_builder(expected_response)
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    parser = DucklingParser(
-        dimensions=["number", "date", "time"], timezone="Asia/Kolkata", locale="en_IN"
-    )
-
-    response = parser._get_entities(body)
-    assert response == expected_response
-
-
-# == Test duckling api returning 500 ==
-@httpretty.activate
-def test_duckling_api_failure() -> None:
-    """
-    Simulate Duckling returning 500.
-    """
-    body = "27th next month"
-    expected_response = [config.mock_date_entity]
-
-    request_callback = request_builder(expected_response, response_code=500)
-
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    parser = DucklingParser(
-        dimensions=["time"], locale="en_IN", timezone="Asia/Kolkata"
-    )
-
-    with pytest.raises(ValueError):
-        parser._get_entities(body)
-
-
-# == Test duckling with timezone info ==
-@httpretty.activate
-def test_duckling_with_tz() -> None:
-    """
-    Using DucklingParser with timezone.
-    """
-    body = "i need it at 5 am"
-    expected_response = [config.mock_time_entity]
-
-    request_callback = request_builder(expected_response)
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    parser = DucklingParser(
-        locale="en_IN", timezone="Asia/Kolkata", dimensions=["time"]
-    )
-
-    response = parser._get_entities(body)
-    assert response == expected_response
-
-
-# == Test duckling with incorrect timezone ==
-def test_duckling_wrong_tz() -> None:
-    """
-    In case the timezone is incorrect or exceptions need to be handled.
-    """
-    body = "i need it at 5 am"
-
-    request_callback = request_builder({})
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    parser = DucklingParser(
-        locale="en_IN", timezone="Earth/Someplace", dimensions=["time"]
-    )
-
-    with pytest.raises(pytz.UnknownTimeZoneError):
-        _ = parser._get_entities(body)
-
-
-# == Test entity structure modifications for numerical entities ==
-def test_entity_mutation_dict() -> None:
-    """
-    This piece of code is run by DucklingParser when the Duckling API
-    returns a set of entities. There are a few keys added/removed.
-    We are making sure of those for numerical entities here.
-    """
-    entities_json = config.mock_number_entity
-    parser = DucklingParser(
-        locale="en_IN", dimensions=["number"], timezone="Asia/Kolkata"
-    )
-    entity = parser._mutate_entity(entities_json)
-
-    assert "range" in entity
-    assert "start" in entity["range"]
-    assert "end" in entity["range"]
-    assert "values" in entity
-    assert entity["values"][0]["value"] == 4
-
-
-# == Test entity structure modifications for time entities ==
-def test_entity_mutation_list() -> None:
-    """
-    This piece of code is run by DucklingParser when the Duckling API
-    returns a set of entities. There are a few keys added/removed.
-    We are making sure of those for time entities here.
-    """
-    entity_json = {
-        "body": "at 5 am",
-        "start": 55,
-        "value": {
-            "values": [
-                {
-                    "value": "2021-01-21T05:00:00.000+05:30",
-                    "grain": "hour",
-                    "type": "value",
-                },
-                {
-                    "value": "2021-01-22T05:00:00.000+05:30",
-                    "grain": "hour",
-                    "type": "value",
-                },
-                {
-                    "value": "2021-01-23T05:00:00.000+05:30",
-                    "grain": "hour",
-                    "type": "value",
-                },
-            ],
-            "value": "2021-01-21T05:00:00.000+05:30",
-            "grain": "hour",
-            "type": "value",
-        },
-        "end": 62,
-        "dim": "time",
-        "latent": False,
-    }
-
-    parser = DucklingParser(
-        locale="en_IN", dimensions=["time"], timezone="Asia/Kolkata"
-    )
-    entity = parser._mutate_entity(entity_json)
-
-    assert "range" in entity
-    assert "start" in entity["range"]
-    assert "end" in entity["range"]
-    assert "values" in entity
-    assert "value" not in entity
-    assert entity["values"][0]["value"] == "2021-01-21T05:00:00.000+05:30"
-
-
-# == Test transformation of entity-json to TimeEntity ==
-def test_entity_json_to_object_time_entity() -> None:
-    """
-    Reshape converts json response from Duckling APIs
-    to dialogy's BaseEntity.
-
-    We are checking for TimeEntity here.
-    """
-    parser = DucklingParser(
-        locale="en_IN", dimensions=["time"], timezone="Asia/Kolkata"
-    )
-    entities_json = [config.mock_time_entity]
-
-    entities = parser._reshape(entities_json)
-    assert isinstance(entities[0], TimeEntity)
-
-
-# == Test transformation of entity-json to TimeIntervalEntity ==
-def test_entity_json_to_object_time_interval_entity():
-    """
-    Reshape converts json response from Duckling APIs
-    to dialogy's BaseEntity.
-
-    We are checking for TimeIntervalEntity here.
-    """
-    parser = DucklingParser(
-        locale="en_IN", dimensions=["time"], timezone="Asia/Kolkata"
-    )
-    entities_json = [config.mock_interval_entity]
-
-    entities = parser._reshape(entities_json)
-    assert isinstance(entities[0], TimeIntervalEntity)
-
-
-# == Test transformation of entity-json with only `from` key in dictionary to TimeIntervalEntity ==
-def test_entity_json_to_object_time_interval_entity_with_only_from_key():
-    """
-    Reshape converts json response from Duckling APIs
-    to dialogy's BaseEntity.
-
-    We are checking for TimeIntervalEntity here.
-    """
-    parser = DucklingParser(
-        locale="en_IN", dimensions=["time"], timezone="Asia/Kolkata"
-    )
-    entities_json = [config.mock_interval_entity_from]
-
-    entities = parser._reshape(entities_json)
-    assert isinstance(entities[0], TimeIntervalEntity)
-
-
-# == Test transformation of entity-json with only `to` key in dictionary to TimeIntervalEntity ==
-def test_entity_json_to_object_time_interval_entity_with_only_to_key():
-    """
-    Reshape converts json response from Duckling APIs
-    to dialogy's BaseEntity.
-
-    We are checking for TimeIntervalEntity here.
-    """
-    parser = DucklingParser(
-        locale="en_IN", dimensions=["time"], timezone="Asia/Kolkata"
-    )
-    entities_json = [config.mock_interval_entity_to]
-
-    entities = parser._reshape(entities_json)
-    assert isinstance(entities[0], TimeIntervalEntity)
-
-
-# == Test transformation of entity-json with neither `from` nor `to` in dictionary to TimeIntervalEntity ==
-def test_bad_interval_entity():
-    """
-    Reshape converts json response from Duckling APIs
-    to dialogy's BaseEntity.
-
-    We are checking for TimeIntervalEntity here.
-    """
-    parser = DucklingParser(
-        locale="en_IN", dimensions=["time"], timezone="Asia/Kolkata"
-    )
-    entities_json = config.mock_bad_interval_entity
-
-    with pytest.raises(TypeError):
-        parser._mutate_entity(entities_json)
-
-
-# == Test transformation of entity-json to NumericalEntity ==
-def test_entity_json_to_object_numerical_entity() -> None:
-    """
-    Reshape converts json response from Duckling APIs
-    to dialogy's BaseEntity.
-
-    We are checking for NumericalEntity here.
-    """
-    entities_json = [
-        {
-            "body": "four",
-            "start": 7,
-            "value": {"value": 4, "type": "value"},
-            "end": 11,
-            "dim": "number",
-            "latent": False,
-        }
-    ]
-    parser = DucklingParser(
-        locale="en_IN", dimensions=["number"], timezone="Asia/Kolkata"
-    )
-    entities = parser._reshape(entities_json)
-    assert isinstance(entities[0], NumericalEntity)
-
-
-# == Test transformation of entity-json to DurationEntity ==
-def test_entity_json_to_object_duration_entity() -> None:
-    """
-    Reshape converts json response from Duckling APIs
-    to dialogy's BaseEntity.
-
-    We are checking for NumericalEntity here.
-    """
-    entities_json = [
-        {
-            "body": "2 days",
-            "start": 0,
-            "value": {
-                "value": 2,
-                "day": 2,
-                "type": "value",
-                "unit": "day",
-                "normalized": {"value": 172800, "unit": "second"},
-            },
-            "end": 6,
-            "dim": "duration",
-            "latent": False,
-        }
-    ]
-    parser = DucklingParser(
-        dimensions=["duration"], locale="en_IN", timezone="Asia/Kolkata"
-    )
-    entities = parser._reshape(entities_json)
-    print(entities)
-    if not isinstance(entities[0], DurationEntity):
-        pytest.fail("expected entities.")
-
-
-# == Test transformation of entity-json to PeopleEntity ==
-def test_entity_json_to_object_people_entity() -> None:
-    """
-    Reshape converts json response from Duckling APIs
-    to dialogy's BaseEntity.
-
-    We are checking for PeopleEntity here.
-
-    """
-    entities_json = [config.mock_people_entity]
-    parser = DucklingParser(
-        locale="en_IN", dimensions=["people"], timezone="Asia/Kolkata"
-    )
-    entities = parser._reshape(entities_json)
-    assert isinstance(entities[0], PeopleEntity)
-
-
-# == Test transformation of unknown entity type ==
-def test_entity_object_not_implemented() -> None:
-    """
-    Reshape converts json response from Duckling APIs
-    to dialogy's BaseEntity.
-
-    We are checking for an unknown entity type here.
-    This would lead to a `NotImplementedError`.
-    """
-    entities_json = [config.mock_unknown_entity]
-    parser = DucklingParser(
-        locale="en_IN", dimensions=["unknown"], timezone="Asia/Kolkata"
-    )
-
-    with pytest.raises(NotImplementedError):
-        parser._reshape(entities_json)
-
-
-# == Test transormation of entity-json with missing value. ==
-def test_entity_object_error_on_missing_value() -> None:
-    """
-    This json has missing `value` key. We can see that we will get a
-    `KeyError` raised, this happens during the validation phase.
-    """
-    entities_json = [
-        {
-            "body": "3 people",
-            "start": 67,
-            "end": 75,
-            "dim": "people",
-            "latent": False,
-        }
-    ]
-    parser = DucklingParser(
-        locale="en_IN", timezone="Asia/Kolkata", dimensions=["people"]
-    )
-
-    with pytest.raises(KeyError):
-        parser._reshape(entities_json)
-
-
-# == Test missing i/o ==
-def test_plugin_io_missing() -> None:
-    """
-    Here we are checking if the plugin has access to workflow.
-    Since we haven't provided `access`, `mutate` to `DucklingParser`
-    we will receive a `TypeError`.
-    """
-    parser = DucklingParser(
-        locale="en_IN", timezone="Asia/Kolkata", dimensions=["time"]
-    )
-    plugin = parser()
-
-    workflow = Workflow(preprocessors=[plugin], postprocessors=[])
-    with pytest.raises(TypeError):
-        workflow.run("")
-
-
-# == Test invalid i/o ==
-@pytest.mark.parametrize(
-    "access,mutate",
-    [
-        (1, 1),
-        (lambda x: x, 1),
-        (1, lambda x: x),
-    ],
-)
-def test_plugin_io_type_mismatch(access, mutate) -> None:
-    """
-    Here we are chcking if the plugin has access to workflow.
-    Since we have provided `access`, `mutate` of incorrect types to `DucklingParser`
-    we will receive a `TypeError`.
-    """
-    parser = DucklingParser(
-        access=access,
-        mutate=mutate,
-        locale="en_IN",
-        dimensions=["time"],
-        timezone="Asia/Kolkata",
-    )
-    plugin = parser()
-
-    workflow = Workflow(preprocessors=[plugin], postprocessors=[])
-    with pytest.raises(TypeError):
-        workflow.run("")
-
-
-# == Test plugin usage with Worfklow ==
-@pytest.mark.parametrize(
-    "body,expected",
-    [
-        (
-            "I need it for 3 people.",
-            [
-                {
-                    "body": "4 people",
-                    "start": 14,
-                    "value": {"value": 4, "type": "value", "unit": "person"},
-                    "end": 22,
-                    "dim": "people",
-                    "latent": False,
-                }
-            ],
-        ),
-        (
-            ["I need it for 3 people."],
-            [
-                {
-                    "body": "4 people",
-                    "start": 14,
-                    "value": {"value": 4, "type": "value", "unit": "person"},
-                    "end": 22,
-                    "dim": "people",
-                    "latent": False,
-                }
-            ],
-        ),
-    ],
-)
-@httpretty.activate
-def test_plugin(body, expected) -> None:
-    """
-    An end-to-end example showing how to use `DucklingParser` with a `Worflow`.
-    """
-
-    def access(workflow):
-        return workflow.input, None
-
-    def mutate(workflow, entities):
-        workflow.output = {"entities": entities}
-
-    parser = DucklingParser(
-        access=access,
-        mutate=mutate,
-        dimensions=["people"],
-        locale="en_IN",
-        timezone="Asia/Kolkata",
-    )
-
-    request_callback = request_builder(expected)
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    workflow = Workflow(preprocessors=[parser()], postprocessors=[])
-    workflow.run(body)
-    assert isinstance(workflow.output["entities"][0], PeopleEntity)
-
-
-# Test plugin with no possible entity from input.
-@httpretty.activate
-def test_plugin_no_entities() -> None:
-    """
-    An end-to-end example showing how `DucklingParser` works in case
-    the input has no entities.
-    """
-    body = "i need it"
-    expected = []
-
-    def access(workflow):
-        return workflow.input, None
-
-    def mutate(workflow, entities):
-        workflow.output = {"entities": entities}
-
-    parser = DucklingParser(
-        access=access,
-        mutate=mutate,
-        dimensions=["people"],
-        locale="en_IN",
-        timezone="Asia/Kolkata",
-    )
-
-    request_callback = request_builder(expected)
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    workflow = Workflow(preprocessors=[parser()], postprocessors=[])
-    workflow.run(body)
-    assert workflow.output["entities"] == []
-
-
-@pytest.mark.parametrize(
-    "body",
-    [42, None, {"key", 42}, [12]],
-)
-@httpretty.activate
-def test_plugin_type_errors(body) -> None:
-    """
-    An end-to-end example showing how `DucklingParser` works in case
-    the input is invalid.
-    """
-
-    def access(workflow):
-        return workflow.input, None
-
-    def mutate(workflow, entities):
-        workflow.output = {"entities": entities}
-
-    parser = DucklingParser(
-        access=access,
-        mutate=mutate,
-        dimensions=["people"],
-        locale="en_IN",
-        timezone="Asia/Kolkata",
-    )
-
-    request_callback = request_builder([])
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    with pytest.raises(TypeError):
-        workflow = Workflow(preprocessors=[parser()], postprocessors=[])
-        workflow.run(body)
-
-
-@httpretty.activate
-def test_plugin_value_errors() -> None:
-    """
-    An end-to-end example showing how `DucklingParser` works in case
-    the input is invalid.
-    """
-
-    def access(workflow):
-        return workflow.input, None
-
-    def mutate(workflow, entities):
-        workflow.output = {"entities": entities}
-
-    parser = DucklingParser(
-        access=access,
-        mutate=mutate,
-        dimensions=["people"],
-        locale="en_IN",
-        timezone="Asia/Kolkata",
-    )
-
-    request_callback = request_builder([], response_code=500)
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    with pytest.raises(ValueError):
-        workflow = Workflow(preprocessors=[parser()], postprocessors=[])
-        workflow.run("")
diff --git a/tests/preprocess/text/config.py b/tests/preprocess/text/config.py
new file mode 100644
index 00000000..9870a41b
--- /dev/null
+++ b/tests/preprocess/text/config.py
@@ -0,0 +1,28 @@
+mock_date_entity = {
+    "body": "on 27th next month",
+    "start": 21,
+    "value": {
+        "values": [
+            {
+                "value": "2021-01-27T00:00:00.000-08:00",
+                "grain": "day",
+                "type": "value",
+            }
+        ],
+        "value": "2021-01-27T00:00:00.000-08:00",
+        "grain": "day",
+        "type": "value",
+    },
+    "end": 39,
+    "dim": "time",
+    "latent": False,
+}
+
+mock_unknown_entity = {
+    "body": "3 foobars",
+    "start": 67,
+    "value": {"value": 3, "type": "foobar", "unit": "person"},
+    "end": 75,
+    "dim": "number",
+    "latent": False,
+}
diff --git a/tests/preprocess/text/test_asserts.yaml b/tests/preprocess/text/test_asserts.yaml
new file mode 100644
index 00000000..98c028ed
--- /dev/null
+++ b/tests/preprocess/text/test_asserts.yaml
@@ -0,0 +1,149 @@
+- description: "test people, date and time entities."
+  input: "I need 4 people on 27th next month. Can I have it at 5 am"
+  mock_entity_json: [{'body': '4 people',
+    'start': 7,
+    'value': {'value': 4, 'type': 'value', 'unit': 'person'},
+    'end': 15,
+    'dim': 'people',
+    'latent': False},
+     {'body': 'on 27th next month',
+      'start': 16,
+      'value': {'values': [{'value': '2021-05-27T00:00:00.000+05:30',
+         'grain': 'day',
+         'type': 'value'}],
+       'value': '2021-05-27T00:00:00.000+05:30',
+       'grain': 'day',
+       'type': 'value'},
+      'end': 34,
+      'dim': 'time',
+      'latent': False},
+     {'body': 'at 5 am',
+      'start': 50,
+      'value': {'values': [{'value': '2021-04-16T05:00:00.000+05:30',
+         'grain': 'hour',
+         'type': 'value'},
+        {'value': '2021-04-17T05:00:00.000+05:30',
+         'grain': 'hour',
+         'type': 'value'},
+        {'value': '2021-04-18T05:00:00.000+05:30',
+         'grain': 'hour',
+         'type': 'value'}],
+       'value': '2021-04-16T05:00:00.000+05:30',
+       'grain': 'hour',
+       'type': 'value'},
+      'end': 57,
+      'dim': 'time',
+      'latent': False}]
+  expected: [{"type": "PeopleEntity"}, {"type": "TimeEntity"}, {"type": "TimeEntity"}]
+
+- description: "numerical entity test"
+  input: "4 items"
+  mock_entity_json: [{'body': 'four',
+  'start': 0,
+  'value': {'value': 4, 'type': 'value'},
+  'end': 4,
+  'dim': 'number',
+  'latent': False}]
+  expected: [{"type": "NumericalEntity"}]
+
+- description: "numerical entity test with a list of strings"
+  input: ["4 items", "four items"]
+  mock_entity_json: [{'body': 'four',
+  'start': 0,
+  'value': {'value': 4, 'type': 'value'},
+  'end': 4,
+  'dim': 'number',
+  'latent': False}]
+  expected: [{"type": "NumericalEntity"}, {"type": "NumericalEntity"}]
+
+- description: "test time entity."
+  input: "27th next month"
+  mock_entity_json: [{'body': '27th next month',
+  'start': 0,
+  'value': {'values': [{'value': '2021-05-27T00:00:00.000+05:30',
+     'grain': 'day',
+     'type': 'value'}],
+   'value': '2021-05-27T00:00:00.000+05:30',
+   'grain': 'day',
+   'type': 'value'},
+  'end': 15,
+  'dim': 'time',
+  'latent': False}]
+  expected: [{"type": "TimeEntity"}]
+
+- description: "test time interval."
+  input: "between 2 to 4 am"
+  mock_entity_json: [{'body': 'between 2 to 4 am',
+  'start': 0,
+  'value': {'values': [{'to': {'value': '2021-04-16T05:00:00.000+05:30',
+      'grain': 'hour'},
+     'from': {'value': '2021-04-16T02:00:00.000+05:30', 'grain': 'hour'},
+     'type': 'interval'},
+    {'to': {'value': '2021-04-17T05:00:00.000+05:30', 'grain': 'hour'},
+     'from': {'value': '2021-04-17T02:00:00.000+05:30', 'grain': 'hour'},
+     'type': 'interval'},
+    {'to': {'value': '2021-04-18T05:00:00.000+05:30', 'grain': 'hour'},
+     'from': {'value': '2021-04-18T02:00:00.000+05:30', 'grain': 'hour'},
+     'type': 'interval'}],
+   'to': {'value': '2021-04-16T05:00:00.000+05:30', 'grain': 'hour'},
+   'from': {'value': '2021-04-16T02:00:00.000+05:30', 'grain': 'hour'},
+   'type': 'interval'},
+  'end': 17,
+  'dim': 'time',
+  'latent': False}]
+  expected: [{"type": "TimeIntervalEntity"}]
+
+- description: "time interval entity with only from value."
+  input: "from 4 am"
+  mock_entity_json: [{'body': 'from 4 am',
+  'start': 0,
+  'value': {'values': [{'from': {'value': '2021-04-16T04:00:00.000+05:30',
+      'grain': 'hour'},
+     'type': 'interval'},
+    {'from': {'value': '2021-04-17T04:00:00.000+05:30', 'grain': 'hour'},
+     'type': 'interval'},
+    {'from': {'value': '2021-04-18T04:00:00.000+05:30', 'grain': 'hour'},
+     'type': 'interval'}],
+   'from': {'value': '2021-04-16T04:00:00.000+05:30', 'grain': 'hour'},
+   'type': 'interval'},
+  'end': 9,
+  'dim': 'time',
+  'latent': False}]
+  expected: [{"type": "TimeIntervalEntity"}]
+
+- description: "time interval entity with only to value"
+  input: "till 2 pm"
+  mock_entity_json: [{'body': 'till 2 am',
+  'start': 0,
+  'value': {'values': [{'to': {'value': '2021-04-17T02:00:00.000+05:30',
+      'grain': 'hour'},
+     'type': 'interval'},
+    {'to': {'value': '2021-04-18T02:00:00.000+05:30', 'grain': 'hour'},
+     'type': 'interval'},
+    {'to': {'value': '2021-04-19T02:00:00.000+05:30', 'grain': 'hour'},
+     'type': 'interval'}],
+   'to': {'value': '2021-04-17T02:00:00.000+05:30', 'grain': 'hour'},
+   'type': 'interval'},
+  'end': 9,
+  'dim': 'time',
+  'latent': False}]
+  expected: [{"type":"TimeIntervalEntity"}]
+
+- description: "duration entity"
+  input: "2 hours"
+  mock_entity_json: [{'body': '2 hours',
+  'start': 0,
+  'value': {'value': 2,
+   'hour': 2,
+   'type': 'value',
+   'unit': 'hour',
+   'normalized': {'value': 7200, 'unit': 'second'}},
+  'end': 7,
+  'dim': 'duration',
+  'latent': False}]
+  expected: [{"type": "DurationEntity"}]
+
+- description: "no entity found."
+  input: "there is no spoon"
+  mock_entity_json: []
+  expected: []
diff --git a/tests/preprocess/text/test_duckling_parser.py b/tests/preprocess/text/test_duckling_parser.py
new file mode 100644
index 00000000..f5c3dae2
--- /dev/null
+++ b/tests/preprocess/text/test_duckling_parser.py
@@ -0,0 +1,287 @@
+import importlib
+import json
+import os
+import pathlib
+from typing import Any, Callable, List
+
+import httpretty
+import pytest
+import pytz
+import yaml
+
+from dialogy.preprocess.text.duckling_plugin import DucklingPlugin
+from dialogy.workflow import Workflow
+from tests.preprocess.text import config
+
+
+def load_tests(test_type):
+    test_dir = pathlib.Path(__file__).parent
+    test_cases_path = os.path.join(test_dir, f"test_{test_type}.yaml")
+    with open(test_cases_path, "r") as handle:
+        test_cases = yaml.load(handle, Loader=yaml.FullLoader)
+        # make any suitable modifications here
+    return test_cases
+
+
+def request_builder(
+    expected_response, response_code=200
+) -> Callable[[Any, Any, Any], List[Any]]:
+    header = "application/x-www-form-urlencoded; charset=UTF-8"
+
+    def request_callback(request, _, response_headers) -> List[Any]:
+        content_type = request.headers.get("Content-Type")
+        assert (
+            content_type == header
+        ), f"expected {header} but received Content-Type: {content_type}"
+        return [response_code, response_headers, json.dumps(expected_response)]
+
+    return request_callback
+
+
+# == Test duckling api returning 500 ==
+@httpretty.activate
+def test_duckling_api_failure() -> None:
+    """
+    Simulate Duckling returning 500.
+    """
+    body = "27th next month"
+    expected_response = [config.mock_date_entity]
+
+    request_callback = request_builder(expected_response, response_code=500)
+
+    httpretty.register_uri(
+        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
+    )
+
+    parser = DucklingPlugin(
+        dimensions=["time"], locale="en_IN", timezone="Asia/Kolkata"
+    )
+
+    with pytest.raises(ValueError):
+        parser._get_entities(body)
+
+
+# == Test duckling with incorrect timezone ==
+def test_duckling_wrong_tz() -> None:
+    """
+    In case the timezone is incorrect or exceptions need to be handled.
+    """
+    body = "i need it at 5 am"
+
+    request_callback = request_builder({})
+    httpretty.register_uri(
+        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
+    )
+
+    parser = DucklingPlugin(
+        locale="en_IN", timezone="Earth/Someplace", dimensions=["time"]
+    )
+
+    with pytest.raises(pytz.UnknownTimeZoneError):
+        _ = parser._get_entities(body)
+
+
+# == Test transformation of unknown entity type ==
+def test_entity_object_not_implemented() -> None:
+    """
+    Reshape converts json response from Duckling APIs
+    to dialogy's BaseEntity.
+
+    We are checking for an unknown entity type here.
+    This would lead to a `NotImplementedError`.
+    """
+    entities_json = [config.mock_unknown_entity]
+    parser = DucklingPlugin(
+        locale="en_IN", dimensions=["unknown"], timezone="Asia/Kolkata"
+    )
+
+    with pytest.raises(NotImplementedError):
+        parser._reshape(entities_json)
+
+
+# == Test missing i/o ==
+def test_plugin_io_missing() -> None:
+    """
+    Here we are checking if the plugin has access to workflow.
+    Since we haven't provided `access`, `mutate` to `DucklingPlugin`
+    we will receive a `TypeError`.
+    """
+    parser = DucklingPlugin(
+        locale="en_IN", timezone="Asia/Kolkata", dimensions=["time"]
+    )
+    plugin = parser()
+
+    workflow = Workflow(preprocessors=[plugin], postprocessors=[])
+    with pytest.raises(TypeError):
+        workflow.run("")
+
+
+# == Test invalid i/o ==
+@pytest.mark.parametrize(
+    "access,mutate",
+    [
+        (1, 1),
+        (lambda x: x, 1),
+        (1, lambda x: x),
+    ],
+)
+def test_plugin_io_type_mismatch(access, mutate) -> None:
+    """
+    Here we are chcking if the plugin has access to workflow.
+    Since we have provided `access`, `mutate` of incorrect types to `DucklingPlugin`
+    we will receive a `TypeError`.
+    """
+    parser = DucklingPlugin(
+        access=access,
+        mutate=mutate,
+        locale="en_IN",
+        dimensions=["time"],
+        timezone="Asia/Kolkata",
+    )
+    plugin = parser()
+
+    workflow = Workflow(preprocessors=[plugin], postprocessors=[])
+    with pytest.raises(TypeError):
+        workflow.run("")
+
+
+@pytest.mark.parametrize(
+    "body",
+    [42, None, {"key", 42}, [12]],
+)
+@httpretty.activate
+def test_plugin_type_errors(body) -> None:
+    """
+    An end-to-end example showing how `DucklingPlugin` works in case
+    the input is invalid.
+    """
+
+    def access(workflow):
+        return workflow.input, None
+
+    def mutate(workflow, entities):
+        workflow.output = {"entities": entities}
+
+    parser = DucklingPlugin(
+        access=access,
+        mutate=mutate,
+        dimensions=["people"],
+        locale="en_IN",
+        timezone="Asia/Kolkata",
+    )
+
+    request_callback = request_builder([])
+    httpretty.register_uri(
+        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
+    )
+
+    with pytest.raises(TypeError):
+        workflow = Workflow(preprocessors=[parser()], postprocessors=[])
+        workflow.run(body)
+
+
+@httpretty.activate
+def test_plugin_value_errors() -> None:
+    """
+    An end-to-end example showing how `DucklingParser` works in case
+    the input is invalid.
+    """
+
+    def access(workflow):
+        return workflow.input, None
+
+    def mutate(workflow, entities):
+        workflow.output = {"entities": entities}
+
+    parser = DucklingPlugin(
+        access=access,
+        mutate=mutate,
+        dimensions=["people"],
+        locale="en_IN",
+        timezone="Asia/Kolkata",
+    )
+
+    request_callback = request_builder([], response_code=500)
+    httpretty.register_uri(
+        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
+    )
+
+    with pytest.raises(ValueError):
+        workflow = Workflow(preprocessors=[parser()], postprocessors=[])
+        workflow.run("")
+
+
+@httpretty.activate
+@pytest.mark.parametrize("payload", load_tests("asserts"))
+def test_plugin_working_cases(payload) -> None:
+    """
+    An end-to-end example showing how to use `DucklingPlugin` with a `Worflow`.
+    """
+    body = payload["input"]
+    mock_entity_json = payload["mock_entity_json"]
+    expected_types = payload["expected"]
+
+    def access(workflow):
+        return workflow.input, None
+
+    def mutate(workflow, entities):
+        workflow.output = {"entities": entities}
+
+    parser = DucklingPlugin(
+        access=access,
+        mutate=mutate,
+        dimensions=["people", "time", "date", "duration"],
+        locale="en_IN",
+        timezone="Asia/Kolkata",
+    )
+
+    request_callback = request_builder(mock_entity_json)
+    httpretty.register_uri(
+        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
+    )
+
+    workflow = Workflow(preprocessors=[parser()], postprocessors=[])
+    workflow.run(body)
+    module = importlib.import_module("dialogy.types.entity")
+
+    if not workflow.output["entities"]:
+        assert workflow.output["entities"] == []
+
+    for i, entity in enumerate(workflow.output["entities"]):
+        class_name = expected_types[i]["type"]
+        assert isinstance(entity, getattr(module, class_name))
+
+
+@httpretty.activate
+@pytest.mark.parametrize("payload", load_tests("exceptions"))
+def test_plugin_expected_failures(payload) -> None:
+    """
+    An end-to-end example showing how to use `DucklingPlugin` with a `Worflow`.
+    """
+    body = payload["input"]
+    mock_entity_json = payload["mock_entity_json"]
+    expected_types = payload["expected"]
+    exceptions = {"TypeError": TypeError, "KeyError": KeyError}
+
+    def access(workflow):
+        return workflow.input, None
+
+    def mutate(workflow, entities):
+        workflow.output = {"entities": entities}
+
+    parser = DucklingPlugin(
+        access=access,
+        mutate=mutate,
+        dimensions=["people", "time", "date", "duration"],
+        locale="en_IN",
+        timezone="Asia/Kolkata",
+    )
+
+    request_callback = request_builder(mock_entity_json)
+    httpretty.register_uri(
+        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
+    )
+
+    workflow = Workflow(preprocessors=[parser()], postprocessors=[])
+    with pytest.raises(exceptions[expected_types]):
+        workflow.run(body)
diff --git a/tests/preprocess/text/test_exceptions.yaml b/tests/preprocess/text/test_exceptions.yaml
new file mode 100644
index 00000000..99df4327
--- /dev/null
+++ b/tests/preprocess/text/test_exceptions.yaml
@@ -0,0 +1,24 @@
+- description: "test time interval."
+  input: "between 2 to 4 am"
+  mock_entity_json: [{'body': 'between 2 to 4 am',
+  'start': 0,
+  'value': {'values': [{'type': 'interval'},
+    {'type': 'interval'},
+    {'type': 'interval'}],
+   'type': 'interval'},
+  'end': 17,
+  'dim': 'time',
+  'latent': False}]
+  expected: "TypeError"
+
+- description: "people entity with a missing value."
+  input: "3 people"
+  mock_entity_json: [{
+    "body": "3 people",
+    "start": 67,
+    "end": 75,
+    "dim": "people",
+    "latent": False
+  }]
+  expected: "KeyError"
+
diff --git a/tests/types/entity/test_entities.py b/tests/types/entity/test_entities.py
index c8c2c107..41fa2b26 100644
--- a/tests/types/entity/test_entities.py
+++ b/tests/types/entity/test_entities.py
@@ -131,12 +131,6 @@ def test_entity_values_key_error():
 
 def test_entity_parser_from_dict():
     mock_entity = make_mock_entity()
-    mock_entity["range"] = {"start": mock_entity["start"], "end": mock_entity["end"]}
-    mock_entity["type"] = "basic"
-    del mock_entity["start"]
-    del mock_entity["end"]
-    mock_entity["values"] = mock_entity["value"]["values"]
-    del mock_entity["value"]
     BaseEntity.from_dict(mock_entity)
 
 
@@ -345,7 +339,6 @@ def test_interval_entity_only_from() -> None:
         values=[value],
     )
     entity.set_value(value=value)
-    print(entity)
     assert entity.value == value