Exemplo n.º 1
0
    def adapt_intents(self):
        intents = {}

        for intent_name in self.intents:
            intents[intent_name] = []

            keywords = self.samples2keywords(self.intents[intent_name],
                                             lang=self.lang)
            self.strict = True  # TODO WIP
            if self.strict:
                intent = AdaptBuilder(intent_name)
                for kw in keywords:
                    if kw["required"]:
                        intent.require(kw["name"])
                    else:
                        intent.optionally(kw["name"])
                intents[intent_name] += [{
                    "intent": intent.build().__dict__,
                    "entities": keywords
                }]

            else:
                print("WARNING: strict is an experimental setting, heavy WIP")

                required_kws = [
                    k for k in keywords if k["required"] and not k.get("regex")
                ]
                optional_kws = [
                    k for k in keywords
                    if not k["required"] and not k.get("regex")
                ]

                for k in required_kws:
                    for s in k["samples"]:
                        new_required_keywords = []
                        for t in tokenize(s):
                            if t in self.stop_words:
                                continue
                            kw = {
                                "name": t + "_token",
                                "required": True,
                                "samples": [t]
                            }
                            new_required_keywords.append(kw)

                        intent = AdaptBuilder(intent_name)
                        for kw in new_required_keywords:
                            if kw["required"]:
                                intent.require(kw["name"])
                            else:
                                intent.optionally(kw["name"])
                        intents[intent_name] += [{
                            "intent":
                            intent.build().__dict__,
                            "entities":
                            new_required_keywords + optional_kws
                        }]

        return intents
Exemplo n.º 2
0
    def wrapper(self):
        for intent_name, info in func(self).iteritems():
            intent = IntentBuilder(intent_name)

            if "require" not in info:
                info["require"] = []
            if "optionally" not in info:
                info["optionally"] = []
            if "one of" not in info:
                info["one of"] = []

            for require in info["require"]:
                intent.require(require)
            for optionally in info["optionally"]:
                intent.optionally(optionally)
            for one_of in info["one of"]:
                intent.one_of(one_of)
            intent = intent.build()

            logger.debug("Adding {} intent through {} plugin".format(
                intent_name, self.__class__.__name__))
            engine_handler.get_engine().register_intent_parser(intent)
            plugins_handler.set_intent_plugin(intent_name,
                                              self.__class__.__name__)
        return func(self)
Exemplo n.º 3
0
    def initialize_intent_parser(self):

        self._intents_container = IntentContainer("%s_cache" % self._name)

        self._adapt_intent_engine = DomainIntentDeterminationEngine()
        self._adapt_intent_engine.register_domain(self._name)

        for intent_name, intent_file_path in self.get_intent_names():
            #print ("###### IntentBuilder: %s, %s" % (intent_name, intent_file_path))
            adapt_intent_builder = IntentBuilder(intent_name)
            for intent_name, intent_example_sentences_array in self.intent_training_file_content(
                    intent_file_path, 'intent'):
                #print ("add intent %s, %s" % (intent_name, intent_example_sentences_array))
                self._intents_container.add_intent(
                    intent_name, intent_example_sentences_array)

            for entity_name, entities_array in self.intent_training_file_content(
                    intent_file_path, 'entities'):
                #print ("add entity %s, %s " % (entity_name, entities_array))
                self._intents_container.add_entity(entity_name, entities_array)

                # adapt
                if entity_name.endswith("_keyword"):
                    for k in entities_array:
                        #print ("add keyword %s to %s" % (k, intent_name))
                        self._adapt_intent_engine.register_entity(
                            k, entity_name, domain=self._name)

                    adapt_intent_builder.require(entity_name)

            adapt_intent = adapt_intent_builder.build()
            self._adapt_intent_engine.register_intent_parser(adapt_intent,
                                                             domain=self._name)

        self._intents_container.train(debug=False)
Exemplo n.º 4
0
    def load_engine(self) -> None:
        """Configure Adapt engine if not already cached."""
        if self.engine is None:
            from adapt.intent import IntentBuilder
            from adapt.engine import IntentDeterminationEngine

            config_path = self.profile.read_path("adapt_config.json")
            if not os.path.exists(config_path):
                return

            # Create empty engine
            self.engine = IntentDeterminationEngine()
            assert self.engine is not None

            # { intents: { ... }, entities: [ ... ] }
            with open(config_path, "r") as config_file:
                config = json.load(config_file)

            # Register entities
            for entity_name, entity_values in config["entities"].items():
                for value in entity_values:
                    self.engine.register_entity(value, entity_name)

            # Register intents
            for intent_name, intent_config in config["intents"].items():
                intent = IntentBuilder(intent_name)
                for required_entity in intent_config["require"]:
                    intent.require(required_entity)

                for optional_entity in intent_config["optionally"]:
                    intent.optionally(optional_entity)

                self.engine.register_intent_parser(intent.build())

            self._logger.debug("Loaded engine from config file %s", config_path)
Exemplo n.º 5
0
    def register_intent(self,
                        intent_name,
                        samples=None,
                        optional_samples=None,
                        rx_samples=None):
        """

        :param intent_name: intent_name
        :param samples: list of required registered entities (names)
        :param optional_samples: list of optional registered samples (names)
        :return:
        """
        super().register_intent(intent_name, samples)
        if not samples:
            samples = [intent_name]
            self.register_entity(intent_name, samples)
        optional_samples = optional_samples or []

        # structure intent
        intent = IntentBuilder(intent_name)
        for kw in samples:
            intent.require(kw)
        for kw in optional_samples:
            intent.optionally(kw)
        self.engine.register_intent_parser(intent.build())
        return intent
Exemplo n.º 6
0
 def build(self):
     """
     Builds out all the options specified and compiles them into the intent
     engine.
     """
     for intent_name, entities in self.entities.items():
         new_intent = IntentBuilder(intent_name)
         for entity_name, data in entities.items():
             # If regex entity.
             if 'values' not in data:
                 self.engine.register_regex_entity(entity_name)
                 # Parse out name in regex (assume between < and >).
                 keyword = entity_name.split('<')[1].split('>')[0]
                 if data['required']:
                     new_intent = new_intent.require(keyword)
                 else:
                     new_intent = new_intent.optionally(keyword)
             else:
                 for value in data['values']:
                     self.engine.register_entity(value, entity_name)
                 if data['required']:
                     new_intent = new_intent.require(entity_name)
                 else:
                     new_intent = new_intent.optionally(entity_name)
         new_intent = new_intent.build()
         self.engine.register_intent_parser(new_intent)
Exemplo n.º 7
0
    def testEmptyTags(self):
        # Validates https://github.com/MycroftAI/adapt/issues/114
        engine = IntentDeterminationEngine()
        engine.register_entity("Kevin",
                               "who")  # same problem if several entities
        builder = IntentBuilder("Buddies")
        builder.optionally("who")  # same problem if several entity types
        engine.register_intent_parser(builder.build())

        intents = [i for i in engine.determine_intent("Julien is a friend")]
        assert len(intents) == 0
Exemplo n.º 8
0
    def make_intents(self, rx):
        rx_combos = [rx]
        rx_combos = expand_rx(rx.strip())
        intents = []
        if interact: pdb.set_trace()

        for combo in rx_combos:
            i_name = '{}{}Intent'.format(self.h_prefix, hash_sum(combo))
            #self.log.debug('combo = {}'.format(combo))

            if re.match('^[a-z0-9 ]+$', combo):
                # keywords only
                entity_type = self.make_entity_type(combo)
                intent = IntentBuilder(
                    re.sub('Keywords?', 'Intent',
                           entity_type)).require(entity_type).build()
                intents.append(intent)
                continue
            self.register_regex(combo)
            parts = re.split('(\(|\))', combo)
            intent_builder = IntentBuilder(i_name)
            section = ''

            for idx in range(len(parts)):
                # separate keywords from names
                part = parts[idx]

                if section and part == '(':
                    # got a complete keyword
                    entity_type = self.make_entity_type(section)
                    intent_builder.require(entity_type)
                    section = '('
                    continue
                section += part
                match = re.match('\(\?P<\w+>.+\)', section)

                if match:
                    # got a named group
                    span = re.search('<\w+>', section).span()
                    entity_type = section[span[0] + 1:span[1] - 1]

                    if not idx == len(parts) - 1 and re.match(
                            '(\?|\*).*', parts[idx + 1]):
                        intent_builder.optionally(entity_type)

                    else:
                        intent_builder.require(entity_type)
                    section = ''
                    continue
            intents.append(intent_builder.build())
            self.log.info('Created intent: {}'.format(str(
                intents[-1].__dict__)))
        return intents
Exemplo n.º 9
0
 def train(self):
     # print("Words:")
     # pprint(self.words)
     # print("")
     # print("Intents:")
     # pprint(self.intent_map['intents'])
     # print("Keywords:")
     # pprint(self.keywords)
     for intent in self.intent_map['intents']:
         required_words = []
         optional_words = []
         # print("Training {}".format(intent))
         # pprint(self.keywords)
         for word in self.intent_map['intents'][intent]['words']:
             intents_count = len(self.intent_map['intents'])
             word_appears_in = len(self.words[word])
             # print("Word: {} Weight: {} Intents: {} Appears in: {}".format(word, weight, intents_count, word_appears_in))
             self.intent_map['intents'][intent]['words'][word][
                 'weight'] = self.intent_map['intents'][intent]['words'][
                     word]['weight'] * (intents_count -
                                        word_appears_in) / intents_count
             if (self.intent_map['intents'][intent]['words'][word]
                 ['required']):
                 # add the word as required.
                 # print("adding '{}' as required".format(word_token))
                 required_words.append(self.add_word(intent, word))
             else:
                 # if the word is a keyword list, add it
                 if (word[:1] + word[-1:] == "{}"):
                     optional_words.append(self.add_word(intent, word))
                 else:
                     if (self.intent_map['intents'][intent]['words'][word]
                         ['weight'] > 0.35):
                         # print("adding '{}' as optional".format(word_token))
                         optional_words.append(self.add_word(intent, word))
         construction = IntentBuilder(intent)
         for keyword in required_words:
             # print("Required word: {}".format(keyword))
             construction = construction.require(keyword)
         for keyword in optional_words:
             # print("Optional word: {}".format(keyword))
             construction = construction.optionally(keyword)
         if (construction):
             # print("Building {}".format(intent))
             self.engine.register_intent_parser(construction.build())
     # pprint(self.intent_map['intents'])
     # print("")
     self.trained = True
Exemplo n.º 10
0
def register_intent(name, engine, *keywords, **kwargs):

    for keyword in keywords:
        engine.register_entity(keyword, name.title() + "Keyword")

    for index, values in kwargs.items():
        for value in values:
            engine.register_entity(value, name.title() + index.title())

    intent = IntentBuilder(name.title() + "Intent")\
        .require("RecycleKeyword")\
        .require(name.title() + "Keyword")

    for index in kwargs:
        intent = intent.optionally(name.title() + index.title())

    intent = intent.build()

    engine.register_intent_parser(intent)
Exemplo n.º 11
0
    def loadIntentSpec(self, domain, data):

        if not 'intent' in data:
            return False

        if not domain in self.engine.domains:
            self.engine.register_domain(domain)

        new_intent = IntentBuilder(data['intent'])

        if 'exact' in data:
            for term in data['exact']:
                self.exact_matches[term] = data['intent']

        if 'required' in data:
            for entity in data['required']:
                for key, value in entity.iteritems():
                    if isinstance(value, basestring):
                        self.engine.register_regex_entity(value, domain=domain)
                        new_intent = new_intent.require(key)
                        continue

                    for keyword in value:
                        self.engine.register_entity(keyword,
                                                    key,
                                                    domain=domain)

                    new_intent = new_intent.require(key)

        if 'optionally' in data:
            for entity in data['optionally']:
                for key, value in entity.iteritems():
                    for keyword in value:
                        self.engine.register_entity(keyword,
                                                    key,
                                                    domain=domain)

                new_intent = new_intent.optionally(key)

        new_intent = new_intent.build()
        self.engine.register_intent_parser(new_intent, domain=domain)

        return True
Exemplo n.º 12
0
    def register_keyword_intent(self,
                                name,
                                samples=None,
                                optionals=None,
                                handler=None,
                                ignore_default_kw=False):
        optionals = optionals or []
        samples = samples or [name]
        intent_name = self.object_type + ':' + name
        intent = IntentBuilder(intent_name)

        if samples and isinstance(samples, list):
            samples = {samples[0]: samples}
        if optionals and isinstance(optionals, list):
            optionals = {optionals[0]: optionals}

        if not ignore_default_kw:
            data = self.load_resource(name)
            if data:
                # merge file data
                for new in data:
                    if new not in samples[name]:
                        samples[name].append(new)

            for optional in optionals:
                data = self.load_resource(optional)
                if data:
                    # merge file data
                    for new in data:
                        optionals[optional] = optionals[optional] or []
                        if new not in optionals[optional]:
                            optionals[optional].append(new)

        for required in samples:
            for kw in samples[required]:
                self.adapt.register_entity(required, kw)
            intent.require(required)
        for optional in optionals:
            for kw in optionals[optional]:
                self.adapt.register_entity(optional, kw)
            intent.optionally(optional)
        self.adapt.register_intent_parser(intent.build())
        self.intents[intent_name] = handler
Exemplo n.º 13
0
    def make_intents_struct(self, struct_list):
        # process new style intent for i18n
        intents = []

        for struct in struct_list:
            # single language

            for i_inf in struct['utterances']:
                # intent info
                i_name = '{}{}Intent'.format(self.h_prefix,
                                             hash_sum(str(i_inf)))
                builder = IntentBuilder(i_name)

                for section in i_inf:
                    section = ''.join(ch for ch in section
                                      if re.match(r'A-Za-z0-9:\|', ch))
                    entity_type = self.make_entity_type(section.split(':')[1])

                    if section.startswith('req:'):
                        builder.require(entity_type)
                        continue

                    elif section.startswith('opt:'):
                        builder.optionally(entity_type)
                        continue

                    elif section.startswith('one:'):
                        entity_types = [
                            self.make_entity_type(e)
                            for e in section.split(':')[1].split('|')
                        ]
                        builder.one_of(entity_types)
                        continue

                    else:
                        # shouldn't be here
                        self.log.error(
                            'Something wrong with the struct: {}'.format(
                                struct))
                intents.append(builder.build())
        return intents
Exemplo n.º 14
0
for intent in DOMTree.getElementsByTagName("intent"):
    builder = IntentBuilder(intent.attributes["name"].value)
    for node in intent.getElementsByTagName("keyword"):
        keyword = node.attributes["name"].value
        required = node.attributes["required"].value
        ktype = node.attributes["type"].value
        if ktype == 'normal':
            for child in node.getElementsByTagName("item"):
                engine.register_entity(child.childNodes[0].nodeValue, keyword)
        else:
            engine.register_regex_entity(node.childNodes[0].nodeValue)
        if required == 'true':
            builder.require(keyword)
        else:
            builder.optionally(keyword)
    engine.register_intent_parser(builder.build())

# create and register weather vocabulary
'''weather_keyword = [
    "weather"
]

for wk in weather_keyword:
    engine.register_entity(wk, "WeatherKeyword")

weather_types = [
    "snow",
    "rain",
    "wind",
    "sleet",
    "sun"
Exemplo n.º 15
0
from adapt.intent import IntentBuilder
from adapt.engine import IntentDeterminationEngine

engine = IntentDeterminationEngine()

schema = json.loads(sys.argv[1])

for entity in schema["entities"]:
	if entity["type"] == "string":
		for value in entity["values"]:
			engine.register_entity(value, entity["name"])
	elif entity["type"] == "regex":
		engine.register_regex_entity(entity["pattern"])

for intent in schema["intents"]:
	ib = IntentBuilder(intent["name"].encode("utf-8"))
	for requirement in intent["requirements"]:
		ib.require(requirement["entity"], requirement["attribute"])
	for optional in intent["optionals"]:
		ib.optionally(optional["entity"], optional["attribute"])
	engine.register_intent_parser(ib.build())

if __name__ == "__main__":
	while True:
		line = sys.stdin.readline()
		query = json.loads(line)
		intents = list(engine.determine_intent(query["input"]))
		response = {"intents": intents}
		print(json.dumps(response))
		sys.stdout.flush()