Adapt - First Open Source Intent Parser Released by Mycroft A.I

@seanfitz what do you think? ^

I’d love to know what you think is “should”, as it appears to me that would match on the string 10, as opposed to any numeric value. I think you want something like

engine.register_regex_entity("(?P<NumericValue>\d+)%")

Yes, I’m sorry.

I took this example as I could have chosen engine.register_regex_entity("(?Pab)c").

Actually, at one point, when recognizing

“ab c” with “(?Pab) c”, I had the good result (i.e. “ab”)

but

“abc” with “(?Pab)c” returned nothing.

And I didn’t understand.
I will do some more tests if I have time :wink:

The keyword ‘play’ indicates a general purpose media playback intent is required. It makes sense to match against a list of titles in the users’ library first. Failing to find an exact match, it will need to build a larger data-set on which to search.

It seems most prudent to search this information progressively until a high confidence match is located. First, by searching a list of songs by the same artists in the user’s library,
then a list of popular songs in the last 2 years,
then a list of iconic classic songs.
then repeating the process with lyrics instead of titles as the user may likely be referencing an iconic lyric in the song instead of the official title

Stopping as soon as a high-confidence match is located
It could run a similar match algorithm for video, audio-books, podcasts, etc. each media type returning their highest result, if multiple media types are returned with similar confidence level, Mycroft could suggest clarification of media-type or artist name.

Since the download/caching of media metadata is done in an incremental cycle, the sequence could be optimized in later releases or customized by the end user trivially.

I don’t see any short-term problems with 3rd party services and directories for this information, though it would be really nice if each Mycroft could search a P2P network of other Mycroft first, before going out to search the WWW. Mycroft units may not be very good at processing requests for each other in real-time, but they could synchronize data-sets of common information like song title lists per artist based on shared interests between the users of the units, (2 users both listen to the same artist, so their units maintain a synchronized list of song titles of that artist)

The first thing I would check is if Mycroft had been asked to play the song previously.

Thinking about it, if this method were to work, a sensible thing to do would be to add a way to inform Mycroft that it had made a mistake: just in case it gets the worng one and so that it doesn’t continue to repeatedly play the wrong song every time

Hi, I played around with adapt-parser, it is nice knowledge based parser, But I would like to know what would happen if text doesn’t come under any trained intent.
the engine should return json with “0.00” confidence, but it is throwing some kind on exception.

‘not {!r}’.format(s.class.name))
TypeError: the JSON object must be str, bytes or bytearray, not ‘NoneType’

for eg:
I trained adapt engine for “Music_Intent” with some words, but tried “hi” to parse which is throwing above mentioned exception.

Help much appreciated

Hi @avi_gaur,

I’m not 100% sure that the adapt engine will return matches with a result of 0. This might be the problem but I’m not sure what statement causes the type error so it’s hard to tell.

Can you show the code you’re using (pasted on pastebin or such)? I’ve tried with the example code in adapt and I can’t quite trigger your exception.

Hi forslund,

Please see below code with problem area marked.

import json
import sys
from adapt.intent import IntentBuilder
from adapt.engine import IntentDeterminationEngine

engine = IntentDeterminationEngine()

weather_keyword = [
    "weather"
]

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

weather_types = [
    "snow",
    "rain",
    "wind",
    "sleet",
    "sun"
]

for wt in weather_types:
    engine.register_entity(wt, "WeatherType")

locations = [
    "Seattle",
    "San Francisco",
    "Tokyo"
]

for loc in locations:
    engine.register_entity(loc, "Location")

weather_intent = IntentBuilder("WeatherIntent")\
    .require("WeatherKeyword")\
    .optionally("WeatherType")\
    .require("Location")\
    .build()

engine.register_intent_parser(weather_intent)

def getIntent(text):
    for intent in engine.determine_intent(text):
        if intent.get('confidence') > 0:
            return json.dumps(intent, indent=4)

if __name__ == '__main__':
    text = input("Enter Your Text: ") # Enter "hi"
    json = json.loads(getIntent(text))  # I am loading it as json but not getting anything incase of missing intent text
    print(json)

So the problem here is Adapt engine making an exit in between if it is not able to find intent. which cause problem to handle unknown intent text.

It would be better if in this case it could return a dict with low confidence and no intent value.

I get what you mean but I don’t quite agree.

To work around your issue you can do something like

def getIntent(text):
    for intent in engine.determine_intent(text):
        if intent and intent.get('confidence') > 0:
            return json.dumps(intent, indent=4)
    return json.dumps({})

The determine_intent is basically an iterator returning available matches one after the other, usually only one but for multi-domain intents it can return several. If this returned empty intents as well it would basically never stop iterating.

In your test case as there are no matches at all the for loop doesn’t even start and the function returns directly. Adding a return statement with a valid json string if no intent is found should resolve your issue.