Skip to content

Commit

Permalink
Update old packages (#161)
Browse files Browse the repository at this point in the history
* update with new packages

* linting

* update mypy

* update poetry file

* update

* revert READE

* revert READE

Co-authored-by: Daksh Varshneya <[email protected]>
  • Loading branch information
dakshvar22 and Daksh Varshneya authored Oct 12, 2022
1 parent bf2e54f commit 3f9bf1d
Show file tree
Hide file tree
Showing 20 changed files with 2,146 additions and 1,093 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Dialogy is a library for building and managing SLU applications.
pip install dialogy
```


Dialogy's CLI supports building and migration of projects. Migration is hard because a few modules need a forced update but a few others
should be retained by the developer. The lack of this expression makes it hard to migrate smoothly. Building new projects should be fairly simple.

Expand Down
32 changes: 16 additions & 16 deletions dialogy/base/input/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ class Input:
"""
Points at the active state (or node) within the conversation graph.
"""

nls_label: Optional[str] = attr.ib(
default=None,
kw_only=True,
Expand Down Expand Up @@ -250,7 +250,11 @@ def __attrs_post_init__(self) -> None:
self, "best_transcript", get_best_transcript(self.transcripts)
)

object.__setattr__(self, "expected_slots", set(self.expected_slots) if self.expected_slots else None)
object.__setattr__(
self,
"expected_slots",
set(self.expected_slots) if self.expected_slots else None,
)

except TypeError:
...
Expand Down Expand Up @@ -306,26 +310,22 @@ def find_entities_in_history(

# Flatten the history to a list of intents
intents: List[Dict[str, Any]] = reduce(
lambda intents, res: intents + res["intents"],
self.history[::-1],
[])
lambda intents, res: intents + res["intents"], self.history[::-1], []
)

# Filter intents by name
required_intents = filter(
lambda intent: intent["name"] in _intent_names,
intents)
lambda intent: intent["name"] in _intent_names, intents
)

# Flatten the intents to a list of slots
slots: List[Dict[str, Any]] = reduce(
lambda slots, intent: slots + intent["slots"],
required_intents,
[])
lambda slots, intent: slots + intent["slots"], required_intents, []
)

# Filter slots by name
required_slots = filter(
lambda slot: slot["name"] in _slot_names,
slots)
required_slots = filter(lambda slot: slot["name"] in _slot_names, slots)

return list(reduce(
lambda entities, slot: entities + slot["values"],
required_slots, []))
return list(
reduce(lambda entities, slot: entities + slot["values"], required_slots, [])
)
6 changes: 2 additions & 4 deletions dialogy/plugins/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
from dialogy.plugins.text.calibration.xgb import CalibrationModel
from dialogy.plugins.text.canonicalization import CanonicalizationPlugin
from dialogy.plugins.text.classification.mlp import MLPMultiClass
from dialogy.plugins.text.classification.retain_intent import \
RetainOriginalIntentPlugin
from dialogy.plugins.text.classification.retain_intent import RetainOriginalIntentPlugin
from dialogy.plugins.text.classification.xlmr import XLMRMultiClass
from dialogy.plugins.text.combine_date_time import CombineDateTimeOverSlots
from dialogy.plugins.text.duckling_plugin import DucklingPlugin
from dialogy.plugins.text.lb_plugin import DucklingPluginLB
from dialogy.plugins.text.list_entity_plugin import ListEntityPlugin
from dialogy.plugins.text.list_search_plugin import ListSearchPlugin
from dialogy.plugins.text.merge_asr_output import MergeASROutputPlugin
from dialogy.plugins.text.slot_filler.rule_slot_filler import \
RuleBasedSlotFillerPlugin
from dialogy.plugins.text.slot_filler.rule_slot_filler import RuleBasedSlotFillerPlugin
from dialogy.plugins.text.address_parser import AddressParserPlugin
from dialogy.plugins.text.error_recovery.error_recovery import ErrorRecoveryPlugin
2 changes: 1 addition & 1 deletion dialogy/plugins/text/classification/xlmr.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def __init__(
nls_label_column: str = const.NLS_LABEL,
args_map: Optional[Dict[str, Any]] = None,
skip_labels: Optional[List[str]] = None,
prompts_map: Dict[Any,Any] = {const.LANG : []},
prompts_map: Dict[Any, Any] = {const.LANG: []},
use_prompt: bool = False,
null_prompt_token: str = const.NULL_PROMPT_TOKEN,
kwargs: Optional[Dict[str, Any]] = None,
Expand Down
106 changes: 62 additions & 44 deletions dialogy/plugins/text/error_recovery/error_recovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Environment:
The scope of variables for error-recovery rules are defined by this class.
Referencing SLU input and output variables for filtering and updates.
"""

intents: List[Intent] = attr.ib(kw_only=True)
"""
Refer to :ref:`Intent<Intent>`
Expand Down Expand Up @@ -159,6 +160,7 @@ def set_item(self, item: Union[Intent, BaseEntity], key: str, value: Any) -> Non
value = value(item) if callable(value) else value
setattr(item, attribute, value)


@attr.s
class BinaryCondition:
"""
Expand All @@ -178,43 +180,45 @@ class BinaryCondition:
:return: _description_
:rtype: _type_
"""

variable: str = attr.ib(kw_only=True)
value: Union[str, Set[str]] = attr.ib(kw_only=True)
operator: Callable[[Any, Any], bool] = attr.ib(kw_only=True)
operations = {
'eq': lambda a, b: a == b,
'ne': lambda a, b: a != b,
'in': lambda a, b: a in b,
'nin': lambda a, b: a not in b,
'gt': lambda a, b: a > b,
'gte': lambda a, b: a >= b,
'lt': lambda a, b: a < b,
'lte': lambda a, b: a <= b,
"eq": lambda a, b: a == b,
"ne": lambda a, b: a != b,
"in": lambda a, b: a in b,
"nin": lambda a, b: a not in b,
"gt": lambda a, b: a > b,
"gte": lambda a, b: a >= b,
"lt": lambda a, b: a < b,
"lte": lambda a, b: a <= b,
}

@classmethod
def from_dict(cls, d: Dict[str, Any]) -> 'BinaryCondition':
def from_dict(cls, d: Dict[str, Any]) -> "BinaryCondition":
default_op_name = "eq"

var_name = list(d.keys()).pop()
op_name = (list(d[var_name].keys()).pop()
op_name = (
list(d[var_name].keys()).pop()
if isinstance(d[var_name], dict)
else default_op_name)
else default_op_name
)

value = d[var_name][op_name] if isinstance(d[var_name], dict) else d[var_name]
if isinstance(value, list):
value = set(value)

return cls(
variable=var_name,
operator=BinaryCondition.operations[op_name],
value=value
variable=var_name, operator=BinaryCondition.operations[op_name], value=value
)

@classmethod
def from_list(cls, d: List[Dict[str, Any]]) -> List['BinaryCondition']:
def from_list(cls, d: List[Dict[str, Any]]) -> List["BinaryCondition"]:
return [cls.from_dict(c) for c in d]


@attr.s
class Rule:
"""
Expand All @@ -225,12 +229,15 @@ class Rule:
1. Search: We apply filters to a resource (one of intents or entities).
2. Action: We perform an action on the resource (one of update, remove).
"""

find: str = attr.ib(kw_only=True)
where: List[BinaryCondition] = attr.ib(converter=BinaryCondition.from_list, kw_only=True) # type: ignore
where: List[BinaryCondition] = attr.ib(converter=BinaryCondition.from_list, kw_only=True) # type: ignore
remove: TRemove = attr.ib(kw_only=True)
update: TUpdate = attr.ib(kw_only=True)

def on_conditions(self, environment: Environment) -> Callable[[Union[Intent, BaseEntity]], bool]:
def on_conditions(
self, environment: Environment
) -> Callable[[Union[Intent, BaseEntity]], bool]:
"""
Pick items within resources when all conditions match.
Expand All @@ -242,17 +249,20 @@ def on_conditions(self, environment: Environment) -> Callable[[Union[Intent, Bas
:rtype: Callable[[Union[Intent, BaseEntity]], bool]
"""
conditions = self.where

def foreach(item: Union[Intent, BaseEntity]) -> bool:
return all(
condition.operator(
environment.get(item, condition.variable),
condition.value
environment.get(item, condition.variable), condition.value
)
for condition in conditions
)

return foreach

def on_inverse(self, environment: Environment) -> Callable[[Union[Intent, BaseEntity]], bool]:
def on_inverse(
self, environment: Environment
) -> Callable[[Union[Intent, BaseEntity]], bool]:
"""
Pick items within resources when no conditions match.
Expand All @@ -265,21 +275,22 @@ def on_inverse(self, environment: Environment) -> Callable[[Union[Intent, BaseEn
:rtype: Callable[[Union[Intent, BaseEntity]], bool]
"""
conditions = self.where

def foreach(item: Union[Intent, BaseEntity]) -> bool:
return not all(
condition.operator(
environment.get(item, condition.variable),
condition.value
environment.get(item, condition.variable), condition.value
)
for condition in conditions
)

return foreach

def _find(
self,
resource: str,
clause: Callable[[Union[Intent, BaseEntity]], bool],
environment: Environment
environment: Environment,
) -> Iterable[Union[Intent, BaseEntity]]:
"""
Find items within a resource that match a condition.
Expand All @@ -293,12 +304,12 @@ def _find(
:return: An iterable of resources filtered by the clause.
:rtype: Iterable[Union[Intent, BaseEntity]]
"""
resources = (environment.intents
if resource == "intents"
else environment.entities)
return filter(clause, resources) # type: ignore
resources = (
environment.intents if resource == "intents" else environment.entities
)
return filter(clause, resources) # type: ignore

def _remove(self, environment: Environment) -> 'Rule':
def _remove(self, environment: Environment) -> "Rule":
"""
Remove items within a resource that match a condition.
Expand All @@ -307,14 +318,18 @@ def _remove(self, environment: Environment) -> 'Rule':
:rtype: Rule
"""
if not self.remove:
return self # pragma: no cover
return self # pragma: no cover
resource_name = self.remove
resources = list(self._find(resource_name, self.on_inverse(environment), environment))
resources = list(
self._find(resource_name, self.on_inverse(environment), environment)
)
if resource_name in Environment.resources and resources:
environment.set(self.remove, resources)
return self

def _transform(self, environment: Environment) -> Callable[[Union[Intent, BaseEntity]], Union[Intent, BaseEntity]]:
def _transform(
self, environment: Environment
) -> Callable[[Union[Intent, BaseEntity]], Union[Intent, BaseEntity]]:
"""
Transform items within a resource as per update rules.
Expand All @@ -323,15 +338,17 @@ def _transform(self, environment: Environment) -> Callable[[Union[Intent, BaseEn
:return: A function that can be used to transform a resource.
:rtype: Callable[[Union[Intent, BaseEntity]], Union[Intent, BaseEntity]]
"""

def foreach(item: Union[Intent, BaseEntity]) -> Union[Intent, BaseEntity]:
if not self.update:
return item # pragma: no cover
return item # pragma: no cover
for key, value in self.update.items():
environment.set_item(item, key, value)
return item

return foreach

def _update(self, environment: Environment) -> 'Rule':
def _update(self, environment: Environment) -> "Rule":
"""
Update items within a resource as per update rules.
Expand All @@ -340,13 +357,15 @@ def _update(self, environment: Environment) -> 'Rule':
:rtype: Rule
"""
resource_name = self.find
resources = self._find(resource_name, self.on_conditions(environment), environment)
resources = self._find(
resource_name, self.on_conditions(environment), environment
)
resources = list(map(self._transform(environment), resources))
if resource_name in Environment.resources and resources:
environment.set(self.find, resources)
return self

def parse(self, environment: Environment) -> 'Rule':
def parse(self, environment: Environment) -> "Rule":
"""
Parse a rule and update the environment.
Expand All @@ -362,10 +381,10 @@ def parse(self, environment: Environment) -> 'Rule':
return self._remove(environment)
if self.update:
return self._update(environment)
return self # pragma: no cover
return self # pragma: no cover

@classmethod
def from_dict(cls, rule: Dict[str, Any]) -> 'Rule':
def from_dict(cls, rule: Dict[str, Any]) -> "Rule":
return cls(
find=str(rule.get("find")),
where=rule.get("where"),
Expand All @@ -374,9 +393,7 @@ def from_dict(cls, rule: Dict[str, Any]) -> 'Rule':
)

@classmethod
def from_list(
cls,
rules: List[Dict[str, Any]]) -> List['Rule']:
def from_list(cls, rules: List[Dict[str, Any]]) -> List["Rule"]:
return [cls.from_dict(rule) for rule in rules]


Expand Down Expand Up @@ -406,7 +423,7 @@ class ErrorRecoveryPlugin(Plugin):
...: from dialogy.types import Intent
In [2]: error_recovery_config = yaml.safe_load('''
...: rules:
...: rules:
...: -
...: find: entities
...: where:
Expand All @@ -431,10 +448,10 @@ class ErrorRecoveryPlugin(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["entities"][0]
In [5]: error_recovery_config = yaml.safe_load('''
...: rules:
...: rules:
...: -
...: find: entities
...: where:
Expand All @@ -459,7 +476,7 @@ class ErrorRecoveryPlugin(Plugin):
.. code-block:: yaml
intent_swap:
-
-
depends_on:
intent: _confirm_
state:
Expand Down Expand Up @@ -492,6 +509,7 @@ class ErrorRecoveryPlugin(Plugin):
update:
intent.name: _issue_resolved_
"""

def __init__(
self,
rules: List[Dict[str, Any]],
Expand Down
Loading

0 comments on commit 3f9bf1d

Please sign in to comment.