dialogy.plugins.text.error_recovery package¶
Submodules¶
dialogy.plugins.text.error_recovery.error_recovery module¶
The goal of this module is to enable:
Richer transitions. Most of our transtions are expressed by maps, we don’t have a way to express transitions as a function over known variables.
We have
triggers
that map to the nextstate
in the conversation.triggers
areintents
in most cases.ML components produce confidence scores for a prediction. Only in cases of low confidence, should we opt for explicit confirmation.
As per our current capabilities, we always have a prompt to confirm.
Here the rule for transition is
(intent, score) -> state
instead of{intent: state}
.Handling ambiguity at the interface. We don’t have an expression to implement “Did you mean X or Y” for resolving ambiguities. We have such prompts for certain deployment yet the effort is the same for enabling such for entities other than X, Y and repeats for every deployment.
Conversation level defaults. In the above example, we can should be able to define conversation level defaults for certain entities.
Personalization. We don’t have provisions for handling user information. We have seen cases where speaker’s information has to be passed around microservices and the API design is driven by urgency. Does this speaker like when the prompts are faster? slower? shorter? longer? While such information is not logged, we also don’t have a way to use it.
These requirements are met by a mature, feature-rich, battle-tested high level language. A language that must expose little noise to its users and offer strong guaranatees of reproducibility, safety and consistency. Building such a language would span work over quarters with dedicated bandwidth of an experienced engineer. Hence we will drop a lot of responsibilities to draft a version that does much less but promises to extend itself to offer coverage of the aforementioned features.
The language should be approachable for existing engineers in the solutions team.
It should take a few hours (< 3) to get productive.
We will implement rich transitions and conversation level defaults.
- class BinaryCondition(*, variable, value, operator)[source]¶
Bases:
object
This class encodes conditions between two operands.
Currently supported operators are:
eq
Equalityne
Non-equalitygte
Greater thange
Greater than or equal tolte
Less thanle
Less than or equal toin
Inclusionnin
Exclusion
- Returns
_description_
- Return type
_type_
- classmethod from_list(d)[source]¶
- Return type
List
[BinaryCondition
]
- operations = {'eq': <function BinaryCondition.<lambda>>, 'gt': <function BinaryCondition.<lambda>>, 'gte': <function BinaryCondition.<lambda>>, 'in': <function BinaryCondition.<lambda>>, 'lt': <function BinaryCondition.<lambda>>, 'lte': <function BinaryCondition.<lambda>>, 'ne': <function BinaryCondition.<lambda>>, 'nin': <function BinaryCondition.<lambda>>}¶
- operator: Callable[[Any, Any], bool]¶
- value: Union[str, Set[str]]¶
- variable: str¶
- class Environment(*, intents, entities, previous_intent=None, current_state=None, expected_slots=NOTHING, bindings=NOTHING)[source]¶
Bases:
object
The scope of variables for error-recovery rules are defined by this class. Referencing SLU input and output variables for filtering and updates.
- bindings: Dict[str, Any]¶
Sub-commands and other variables should be stored here. API is WIP.
- current_state: Optional[str]¶
Read only; used to filter intents/entities if a condition is met. Read More
- entities: List[dialogy.types.entity.base_entity.BaseEntity]¶
Refer to BaseEntity Contains a list of entities of varying types. Iterable field, can also be modified by update queries.
- expected_slots: Set[str]¶
Read only; used to filter intents/entities if a condition is met. Read More
- get(item, key)[source]¶
Seek a variable from the context set in the environment.
- Parameters
item (Union[Intent, BaseEntity]) – Either an intent or entity.
key (str) – A property within the item or environment.
- Returns
The value bound to the key.
- Return type
Any
- intents: List[dialogy.types.intent.Intent]¶
Refer to Intent
Contains the list of intents predicted expected in sorted order of confidence score. Iterable field, can also be modified by update queries.
- iterables = {'entity', 'intent'}¶
- last_day_of_month(item)[source]¶
Returns the last day of the month for the given TimeEntity.
- Parameters
item (TimeEntity) – A time entity.
- Returns
The last day of the month
- Return type
int
- last_day_of_week(item)[source]¶
Returns the last day of the week for the given TimeEntity.
- Parameters
item (TimeEntity) – A time entity.
- Returns
The last day of the week.
- Return type
int
- property predicted_intent: str¶
We are assuming intents would be sorted in descending order of confidence scores. Hence the first element is the predicted intent as it has the best score.
- Return type
str
- previous_intent: Optional[str]¶
Read only; used to filter intents/entities if a condition is met. Read More
- resources = {'entities', 'intents'}¶
- set(key, value)[source]¶
Bind a value to a variable in the environment.
- Parameters
key (str) – A variable name defined in the environment.
value (List[Union[Intent, BaseEntity]]) – The value to bound to the variable.
- Returns
None
- Return type
None
- set_item(item, key, value)[source]¶
Bind a value to either Intent or Entity.
- Parameters
item (Union[Intent, BaseEntity]) – Either an intent or entity.
key (str) – A property within the item.
value (Any) – The value to bound to the property or a function identifier.
- Return type
None
- class ErrorRecoveryPlugin(rules, dest=None, guards=None, replace_output=True, debug=False)[source]¶
Bases:
dialogy.base.plugin.Plugin
rules: - find: entities where: - entity.grain: month - entity.entity_type: in: ["date", "time", "datetime"] update: entity.day: :last_day_of_month
We can use the above rule like so:
In [1]: import yaml ...: from dialogy.plugins import ErrorRecoveryPlugin, DucklingPlugin ...: from dialogy.workflow import Workflow ...: from dialogy.base import Input ...: from dialogy.types import Intent ...: In [2]: error_recovery_config = yaml.safe_load(''' ...: rules: ...: - ...: find: entities ...: where: ...: - entity.grain: month ...: - entity.entity_type: ...: in: ["date", "time", "datetime"] ...: - predicted_intent: "future_date" ...: update: ...: entity.day: :last_day_of_month ...: ''') ...: In [3]: duckling_plugin = DucklingPlugin(dimensions=["time"], dest="output.entities") ...: workflow = Workflow([duckling_plugin]) ...: workflow.set("output.intents", [Intent(name="future_date", score=0.99)]) ...: _, out = workflow.run(input_=Input(utterances="this month")) ...: # The default value is 1st of the month ...: out["entities"][0] ...: Out[3]: {'range': {'start': 0, 'end': 10}, 'body': 'this month', 'type': 'value', 'parsers': ['DucklingPlugin'], 'score': 1.0, 'alternative_index': 0, 'value': '2022-08-01T00:00:00.000+00:00', 'entity_type': 'date', 'grain': 'month'} In [4]: error_recovery_plugin = ErrorRecoveryPlugin(rules=error_recovery_config["rules"]) ...: duckling_plugin = DucklingPlugin(dimensions=["time"], dest="output.entities") ...: workflow = Workflow([duckling_plugin, error_recovery_plugin]) ...: workflow.set("output.intents", [Intent(name="future_date", score=0.99)]) ...: _, out = workflow.run(input_=Input(utterances="this month")) ...: # But with error recovery, we get the last day of the month ...: out["entities"][0] ...: Out[4]: {'range': {'start': 0, 'end': 10}, 'body': 'this month', 'type': 'value', 'parsers': ['DucklingPlugin'], 'score': 1.0, 'alternative_index': 0, 'value': '2022-08-31T00:00:00+00:00', 'entity_type': 'date', 'grain': 'month'} In [5]: error_recovery_config = yaml.safe_load(''' ...: rules: ...: - ...: find: entities ...: where: ...: - entity.grain: month ...: - entity.entity_type: ...: in: ["date", "time", "datetime"] ...: - predicted_intent: "some-other-intent" # Hence the rule won't match ...: update: ...: entity.day: :last_day_of_month ...: ''') ...: In [6]: error_recovery_plugin = ErrorRecoveryPlugin(rules=error_recovery_config["rules"]) ...: duckling_plugin = DucklingPlugin(dimensions=["time"], dest="output.entities") ...: workflow = Workflow([duckling_plugin, error_recovery_plugin]) ...: workflow.set("output.intents", [Intent(name="future_date", score=0.99)]) ...: _, out = workflow.run(input_=Input(utterances="this month")) ...: # Only if the conditions are satisfactory. ...: out["entities"][0] ...: Out[6]: {'range': {'start': 0, 'end': 10}, 'body': 'this month', 'type': 'value', 'parsers': ['DucklingPlugin'], 'score': 1.0, 'alternative_index': 0, 'value': '2022-08-01T00:00:00.000+00:00', 'entity_type': 'date', 'grain': 'month'}
To migrate from the previous intent renaming plugin, here’s an example config:
intent_swap: - depends_on: intent: _confirm_ state: in: - CONFIRM_VIEWING_POST_HR - CONFIRM_VIEWING_POST_ACCOUNT_RESUMPTION - CONFIRM_VIEWING_POST_ACCOUNT_ACTIVATION - CONFIRM_VIEWING_POST_ASSET_RESUMPTION - CONFIRM_VIEWING_POST_INPUT_CHECK - CONFIRM_VIEWING_POST_RECONNECTION rename: _issue_resolved_
You would express this as:
rules: - find: intents where: - intent.name: _confirm_ - state: in: - CONFIRM_VIEWING_POST_HR - CONFIRM_VIEWING_POST_ACCOUNT_RESUMPTION - CONFIRM_VIEWING_POST_ACCOUNT_ACTIVATION - CONFIRM_VIEWING_POST_ASSET_RESUMPTION - CONFIRM_VIEWING_POST_INPUT_CHECK - CONFIRM_VIEWING_POST_RECONNECTION update: intent.name: _issue_resolved_
- class Rule(*, find, where, remove, update)[source]¶
Bases:
object
We encode events within a conversation turn as a rule.
A rule can be broken down to 2 operations:
Search: We apply filters to a resource (one of intents or entities).
Action: We perform an action on the resource (one of update, remove).
- find: str¶
- on_conditions(environment)[source]¶
Pick items within resources when all conditions match.
We require this to update a set of items that match the conditions.
- Parameters
environment (Environment) – A data-structure that describes a set of bound variables.
- Returns
A function that can be used to filter a resource.
- Return type
Callable[[Union[Intent, BaseEntity]], bool]
- on_inverse(environment)[source]¶
Pick items within resources when no conditions match.
We require this to retain a set of items that don’t match the conditions. That is the remove operation.
- Parameters
environment (Environment) – A data-structure that describes a set of bound variables.
- Returns
A function that can be used to filter a resource.
- Return type
Callable[[Union[Intent, BaseEntity]], bool]
- parse(environment)[source]¶
Parse a rule and update the environment.
We parse the rule and either update or remove items within intents or entities as per the clause described in the rule.
- Parameters
environment (Environment) – A data-structure that describes a set of bound variables.
- Returns
Remove or Update resources.
- Return type
- remove: Optional[str]¶
- update: Optional[Dict[str, Any]]¶