Developing a skill for Mycroft

Avg. 6 minute(s) of reading

On my previous post (the one about Ubuntu and my school exam day), I briefly mentioned that I created a small skill for the Mycroft A.I. assistant (https://mycroft.ai/). Let's talk about that.

Recap

On my previous post (the one about Ubuntu and my school exam day), I briefly mentioned that I created a small skill for the Mycroft A.I. assistant. If you read it, you should remember that, because it was the reason for the whole Ubuntu ordeal after all.

The current state of my skill

The skill was meant to be a really quick and 'dirty' hack to get youtube music playback working, but it turned out a lot nicer than I thought it would ever be. As a matter of fact, it turned out so nicely that I even added to my blog's projects page.
At the moment of writing, there are only 4 things about the skill that I'm not happy with:

  • I haven't created tests, which are (probably) important, for the skill;
  • Instead of telling you the title of the video that's currently playing (when queried), it tells you the name that it heard from you;
  • The skill can't search for youtube playlists. It can only find youtube playlists if you give it a link to the playlist, but it can't do that using keywords. This is because I couldn't find a way to do that using youtube-dl;
  • It is not possible to cancel a download after it has started.

    From this 4 problems, the ones that I'm most likely to take care of are the first two, because a fix for the third problem would most likely require me to implement something that youtube-dl can't do (which and I don't feel like doing) and the last problem is not very important.

    TLDR: The skill is working very well in its current state but could use more features, namely: better youtube playlist support.

The start of the skill development

I'm going to be honest, I was a bit scared of it being too difficult to start the skill development, but I still told my friend that it would be 'easy peasy'. This was mostly because the only problem I was seeing was: "How does Mycroft work?".

Turns out it really was easy to start. The development is in Python, which is extremely easy, and Mycroft provides a really great introductory guide to skill development. If you have experience with object-oriented programming, you should have no problems developing new skills for Mycroft (you don't really need to know Python to code in Python).
If you're thinking about creating a new skill/editing an existing one, I recommend you to check out Mycroft's Hello World skill.

Stuff about 'intents'

Intents are the only thing I found about Mycroft that can be somewhat confusing in the beginning (at least it was for me).

There are 2 types of intents:

  • Adapt intents - these are triggered by a list of keywords (the list can be a single keyword). Bellow is an example adapt intent handler taken from Mycroft's hello world skill:
# example taken from Mycroft's Hello world skill

@intent_handler(IntentBuilder('ThankYouIntent').require('ThankYouKeyword')) def
handle_thank_you_intent(self, message): """ This is an Adapt intent handler, it
is triggered by a keyword.""" self.speak_dialog("welcome")
  • Pedatious intents - these are triggered by a list of sample sentences. They are fascinating, because you can quickly train the A.I. using a relatively small list of sentences. This list of sentences, supports regex, so you can quickly and easily increase your sample size. Below is an example pedatious intent handler adapted from the skill I created:
# example adapted from the skill I developed
@intent_handler("Youtubedl.intent")
def handle_youtubedl_intent(self, message):
  """ This is a Padatious intent handler.
  It is triggered using a list of sample phrases."""
  vid_name = message.data.get("vid")
  self.log.debug("Current queue:", self.queue)
  if not vid_name:
    self.speak_dialog("youtubedl")
  else:
    self.download_vid(vid_name)
    self.log.info("Done downloading video youtubedl.")
  self.log.debug("Done youtubedl.")
</code></pre>

It should be noted that you need to import from adapt.intent import IntentBuilder and from mycroft import MycroftSkill, intent_handler to use Mycroft (import other modules too if you need them).

Vocab files and getting information from the user

These files are located inside the vocab// directory of a project's root ( could be, for example, en-us and they can either contain keywords to trigger adapt intents or a list of sentences (supporting regex) to train an pedatious intent.

For example, you could have a ThankYouKeyword.voc file with the following contents (file used on the decorator of adapt intent example):

thank you
thanks

So the intent in the first code example above would be triggered by either one of these sentences.

You can also have, as an example, a Youtubeddl.intent file with the following contents (file used on the decorator of pedatious intent example):

youtube {vid}
youtube (play | start | download) {vid}

This allows out intent to be triggered by a more complex set of sentences. In the example above, Our intent would be triggered by sentences like: "youtube stream of consciousness", "youtube play dora the explorer" and "youtube start something" (the | means or).
It is also possible to get information from the user using this type of intent (pedatious). In this case, we can extract the {vid} component of the message (you can define all the component you want) using message.data.get("vid"), e.g.: if the user says "youtube start dora the explorer", our intent will be triggered and the {vid} component will be "dora the explorer".

Dialog

It is possible to tell Mycroft to speak a given sentence using self.speak_dialog(string), where string is either a sentence or the name of a dialog File. You could use self.speak_dialog("Hello, my name is Mycroft!") to make Mycroft say: "Hello, my name is Mycroft!", but using vocab files has an important extra feature.

Vocab files allow you to simulate a more human-like speech pattern by writing multiple sentences with the same meaning in the file, so one is selected randomly each time. You could have a greeting.dialog file inside the dialog// directory of your project's root ( could be, for example, en-us) with the following contents:

Good to see you!
Greeting!
Hello!
Hey!
Hi!
Nice to see you!
Pleased to see you!

To tell Mycroft to speak a sentence from that file, you'd use self.speak_dialog("greeting"). Notice the .dialog part missing from the file name. You can omit that part when calling files (it was something that took me a while to notice).

Logs

It is useful to log information of what's happening in your skill, both for debugging and to provide extra information to the end user. At the time of writing, Mycroft provides 5 different types of log messages: info, debug, warning, error, and exception.
To use them, you just need to write self.log.<log-type>(string), where <log-type> is one of the types above and string is the text that will be written, e.g.: self.log.info("Potato evaluation skill triggered."). The aspect (for example color) of the log message depends on its type.

Closing words

There isn't a lot needed to start creating a skill for Mycroft (besides an idea and some programming skills). It is simple to use and develop for.

I hope this blog post isn't too disorganized. It was based on the notes I took when learning how to develop a skill for Mycroft so it might be a little 'all over the place'. I believe it still should be a good resource to show some small usage examples, and to incentivize people to give Mycroft a try.

This post will come out a few days later than I was expecting (I was having trouble concentrating on writing). Still, I hope you had a good St. Valentine's Day (even if you're single). Mine was pretty good.
Stay safe :P