Taking Control of the Dialog Management State Machine
Justin Jeffress Mar 16, 2018
Share:
Dialog Management Tutorial Tips & Tools
Blog_Header_Post_Img

Dialog management is a great way to collect the set of required slots that your intent needs to perform a task for your customers, since it greatly reduces the necessary coding required to reprompt for missing slot values.

From your interaction model, you mark which slots are required and provide a set of prompts and utterances for each required slot. From your backend, you delegate the collection of the slots to Alexa. If your customer didn't provide a required slot value, Alexa will use the provided prompts to ask the customer to fill the missing slot and the provided utterances to fill the slot with a value.

I often get the question from Alexa developers, "Can I override the prompts in code?" One great benefit of using dialog management is that Alexa creates and manages a state machine for you. Your backend code can check the state and not only override prompts, but also perform complex logic that you might need to solve a particular edge case.

Each interaction between the customer and Alexa during dialog management allows to you hook into the state machine and perform your own logic. The request includes the dialogState so you can update your code to function differently based upon the state.

Identifying Dialog Management State

Dialog management has three states, STARTED, IN_PROGRESS, and COMPLETED. When actively capturing required slots through dialog management, the JSON that is sent to your service will include dialogState. The snippet of JSON below includes dialogState, which indicates that we are in dialog management.

Copied to clipboard
{
   ...  
   "request": {
      "type": "IntentRequest",
      "requestId": "amzn1.echo-api.request.",
      "timestamp": "2018-03-07T21:52:27Z",
      "locale": "en-US",
      "intent": {
         "name": "PetMatchIntent",
         "confirmationStatus": "NONE",
         "slots": {
            "size": {
               "name": "size",
               "confirmationStatus": "NONE"
            },
            "temperament": {
               "name": "temperament",
               "confirmationStatus": "NONE"
            },
            "energy": {
               "name": "energy",
               "confirmationStatus": "NONE"
            }
         }
      },
      "dialogState": "STARTED"
   }
   ...
}

From your skill, you can check the dialogState and perform an action like setting default values, or preloading information from a web service. You can even inspect the slots that have been filled. You can check the dialogState by looking at the request, this.event.request.dialogState and access the slots through the request’s intent this.event.request.intent.slots.

Setting Default Values

Let's take a look at how you would set medium as the default value for size, and then ask the customer if the default is okay.

Copied to clipboard
function delegateSlotCollection() {

   if (this.event.request.dialogState == 'STARTED') {
      let size = this.event.request.intent.slots.size
      if (!size.value && size.confirmationStatus !== 'CONFIRMED') {
         this.event.request.intent.slots.size.value = 'medium';
         let speechOutput = 'You did not provide a value for size, so I chose medium. Is that ok?';        let reprompt = 'So you want a medium sized dog?'
         this.emit(':confirmSlot','size', speechOutput, reprompt);
      } else {
         this.emit(':delegate');
      }
   } else if (this.event.request.dialogState !== 'COMPLETED') {
      this.emit(':delegate');
   } else {
      return this.event.request.intent;
   }
}

First, we are checking the dialogState. If it's STARTED and the size slot is empty and hasn't been confirmed, we then set the value to medium, our default, and emit :confirmSlot. Alexa will then say to the customer, "You did not select a size, so I chose medium. Is that okay?" If the customer says, "Yes" the value will be confirmed. If the customer says "No," size.confirmationStatus will become DENIED. If you do nothing else here, dialog management will continue prompting for each required slot in the order that you specified in your interaction model. You can change the order by clicking the up and down arrows or typing the number into the order box.

Alexa Blog

Pet match will ask for pet, size, temperament and energy in that order unless for example, the user provided a slot for pet and temperament. It will then ask for size followed by energy.

Overriding Prompts

If you wanted to override the prompt that you set in your interaction model, you can do so using :elicitSlot.

Copied to clipboard
let speechOutput = "There are dogs that are, tiny, small, medium, and large, which would you like?";
let repromt = "Say a size like tiny, small, medium, or large.";

this.emit(':elicitSlot', 'size', speechOutput, reprompt);

Here we are simply telling elicitSlot to elicit the size slot. Alexa will use the speechOut to prompt the customer. If the customer takes longer than 8 seconds to reply, Alexa will ask again using reprompt. If you wanted to load your prompts from a database, or change them based on the information previously provided, the above example will be useful to you.

Pulling the Ripcord on Dialog Management

There may be times you want to jump out of dialog management early. For example, you have three slots, A, B, and C and you need A or B and C. Programmatically you could check which slots have been provided, and then jump out when the customer has provided either A or B and C. Once the condition has been met, you can set dialogState to COMPLETED. I’ll go into detail about how I solved this exact problem with dialog management in a future post.

I hope this post has helped you understand how you can leverage dialog management to delegate the state management to Alexa. You're able to hook into it and override the default behavior. If you have any questions, let's continue you the discussion. You can contact me at @sleepydeveloper or seek me out at an Alexa Dev Days in your city.

More Resources on Dialog Management