Skip to content

Commit

Permalink
adapt backwards compat (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
JarbasAl authored Dec 29, 2023
1 parent 62e667d commit f45e521
Showing 1 changed file with 129 additions and 121 deletions.
250 changes: 129 additions & 121 deletions ovos_workshop/intents.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,133 +2,141 @@
from threading import RLock
from typing import List, Tuple, Optional

from ovos_utils.log import LOG, log_deprecation
from ovos_bus_client.util import get_mycroft_bus
from ovos_bus_client.message import Message, dig_for_message
from ovos_bus_client.util import get_mycroft_bus
from ovos_utils.log import LOG, log_deprecation

try:
from adapt.intent import IntentBuilder, Intent
# backwards compat isinstancechecks
from adapt.intent import IntentBuilder as _IB, Intent as _I
except ImportError:
# adapt is optional
_I = object
_IB = object


class Intent(_I):
def __init__(self, name="", requires=None, at_least_one=None, optional=None):
"""Create Intent object
Args:
name(str): Name for Intent
requires(list): Entities that are required
at_least_one(list): One of these Entities are required
optional(list): Optional Entities used by the intent
"""
self.name = name
self.requires = requires or []
self.at_least_one = at_least_one or []
self.optional = optional or []

def validate(self, tags, confidence):
"""Using this method removes tags from the result of validate_with_tags
Returns:
intent(intent): Results from validate_with_tags
"""
if _I is not object:
return super().validate(tags, confidence)
raise NotImplementedError("please install adapt-parser")

def validate_with_tags(self, tags, confidence):
"""Validate whether tags has required entites for this intent to fire
Args:
tags(list): Tags and Entities used for validation
confidence(float): The weight associate to the parse result,
as indicated by the parser. This is influenced by a parser
that uses edit distance or context.
Returns:
intent, tags: Returns intent and tags used by the intent on
failure to meat required entities then returns intent with
confidence
of 0.0 and an empty list for tags.
"""
if _I is not object:
return super().validate_with_tags(tags, confidence)
raise NotImplementedError("please install adapt-parser")

class Intent:
def __init__(self, name, requires=None, at_least_one=None, optional=None):
"""Create Intent object
Args:
name(str): Name for Intent
requires(list): Entities that are required
at_least_one(list): One of these Entities are required
optional(list): Optional Entities used by the intent
"""
self.name = name
self.requires = requires or []
self.at_least_one = at_least_one or []
self.optional = optional or []

def validate(self, tags, confidence):
"""Using this method removes tags from the result of validate_with_tags
Returns:
intent(intent): Results from validate_with_tags
"""
raise NotImplementedError("please install adapt-parser")

def validate_with_tags(self, tags, confidence):
"""Validate whether tags has required entites for this intent to fire
Args:
tags(list): Tags and Entities used for validation
confidence(float): The weight associate to the parse result,
as indicated by the parser. This is influenced by a parser
that uses edit distance or context.
Returns:
intent, tags: Returns intent and tags used by the intent on
failure to meat required entities then returns intent with
confidence
of 0.0 and an empty list for tags.
"""
raise NotImplementedError("please install adapt-parser")


class IntentBuilder:
"""
IntentBuilder, used to construct intent parsers.
Attributes:
at_least_one(list): A list of Entities where one is required.
These are separated into lists so you can have one of (A or B) and
then require one of (D or F).
requires(list): A list of Required Entities
optional(list): A list of optional Entities
name(str): Name of intent
Notes:
This is designed to allow construction of intents in one line.
Example:
IntentBuilder("Intent")\
.requires("A")\
.one_of("C","D")\
.optional("G").build()
"""

def __init__(self, intent_name):
"""
Constructor
Args:
intent_name(str): the name of the intents that this parser
parses/validates
"""
self.at_least_one = []
self.requires = []
self.optional = []
self.name = intent_name

def one_of(self, *args):
"""
The intent parser should require one of the provided entity types to
validate this clause.
Args:
args(args): *args notation list of entity names
Returns:
self: to continue modifications.
"""
self.at_least_one.append(args)
return self

def require(self, entity_type, attribute_name=None):
"""
The intent parser should require an entity of the provided type.
Args:
entity_type(str): an entity type
attribute_name(str): the name of the attribute on the parsed intent.
Defaults to match entity_type.
Returns:
self: to continue modifications.
"""
if not attribute_name:
attribute_name = entity_type
self.requires += [(entity_type, attribute_name)]
return self

def optionally(self, entity_type, attribute_name=None):
"""
Parsed intents from this parser can optionally include an entity of the
provided type.
Args:
entity_type(str): an entity type
attribute_name(str): the name of the attribute on the parsed intent.
Defaults to match entity_type.
Returns:
self: to continue modifications.
"""
if not attribute_name:
attribute_name = entity_type
self.optional += [(entity_type, attribute_name)]
return self

def build(self):
"""
Constructs an intent from the builder's specifications.
:return: an Intent instance.
"""
return Intent(self.name, self.requires,
self.at_least_one, self.optional)

class IntentBuilder(_IB):
"""
IntentBuilder, used to construct intent parsers.
Attributes:
at_least_one(list): A list of Entities where one is required.
These are separated into lists so you can have one of (A or B) and
then require one of (D or F).
requires(list): A list of Required Entities
optional(list): A list of optional Entities
name(str): Name of intent
Notes:
This is designed to allow construction of intents in one line.
Example:
IntentBuilder("Intent")\
.requires("A")\
.one_of("C","D")\
.optional("G").build()
"""

def __init__(self, intent_name):
"""
Constructor
Args:
intent_name(str): the name of the intents that this parser
parses/validates
"""
self.at_least_one = []
self.requires = []
self.optional = []
self.name = intent_name

def one_of(self, *args):
"""
The intent parser should require one of the provided entity types to
validate this clause.
Args:
args(args): *args notation list of entity names
Returns:
self: to continue modifications.
"""
self.at_least_one.append(args)
return self

def require(self, entity_type, attribute_name=None):
"""
The intent parser should require an entity of the provided type.
Args:
entity_type(str): an entity type
attribute_name(str): the name of the attribute on the parsed intent.
Defaults to match entity_type.
Returns:
self: to continue modifications.
"""
if not attribute_name:
attribute_name = entity_type
self.requires += [(entity_type, attribute_name)]
return self

def optionally(self, entity_type, attribute_name=None):
"""
Parsed intents from this parser can optionally include an entity of the
provided type.
Args:
entity_type(str): an entity type
attribute_name(str): the name of the attribute on the parsed intent.
Defaults to match entity_type.
Returns:
self: to continue modifications.
"""
if not attribute_name:
attribute_name = entity_type
self.optional += [(entity_type, attribute_name)]
return self

def build(self):
"""
Constructs an intent from the builder's specifications.
:return: an Intent instance.
"""
return Intent(self.name, self.requires,
self.at_least_one, self.optional)


def to_alnum(skill_id: str) -> str:
Expand Down

0 comments on commit f45e521

Please sign in to comment.