Wizarding

Wizard, short for Wizard of Oz, is when you want a human operator to trigger certain actions instead of have automatic triggers like user speech and engagement. This is extremely useful in the early stages of building a skill, when you haven't yet invested in testing the skill with users to make sure your NLU model is solid. Wizarding also comes in handy for skills when you for other reasons want to manually move a skill forward, for example a stage presentation where you want something more robust than voice activation.

Wizarding is easiest done by defining a button/button handler in the flow. The buttons will then appear in the dashboard page and the dedicated wizard page in the web interface.

Note: In some scenarios you might need more customization than offered with this built-in wizarding tool. For these cases, we recommend creating a custom wizarding GUI (see GUI docs).

Adding buttons

Buttons and button-handlers are added simultaneously through the onButton handler available in any state. Buttons have a few important properties:

  • They are state-dependent similar to other handlers. I.e, a button will only show if you are in the state where you defined the button, or in any state inheriting this state.
  • They can be overridden by providing the optional id parameter to both buttons. A child state's button will always override a parent state's button if they have the same id. An button that overrides another button will stay in place of the overridden button for operator convenience.
  • They can be defined explicitly by creating a button and adding it to an onButton handler or implicitly by directly defining an onButton handler.

Buttons can be defined implicitly through the onButton handler as in the following example (also showing how to override a button):

val ParentState = state {
    onButton("myOverriddenButton", id="123") {
    // will be overridden when in MyState since the buttons have the same id
  }
}

val MyState = state(ParentState) {
    onButton("My New Button", id="123") {
      // This will override the previous MyButton when we are in this state
    }

    onButton("My Other Button"){
      /* Creates a new small red button with the label "My Label".
      */
    }
}

The below example shows how to explicitly define a button and then add it to the onButton handler, as well as how to reuse the same button formatting by assigning new buttons as copies of an existing button. When doing this, the copy will always get a new id unless the id is set.

val myButton = Button("My First Button")
val myOtherButton = myButton.copy(label="My Other Button")

val parentState = state {
  onButton(myButton) {
    // ...
  }

  onButton(myOtherButton) {
    // will get the same properties but a new label and a new id
  }

  onButton(myButton.copy(label="My Third Button")) {
    // will get the same properties but a new label
  }
}

Assigning keyboard-keys to buttons

You can assign a keyboard key to a wizard-button with the key parameter to onButton("myButton", key = "e"). More information on the values for KeyboardEvent keys can be found at Mozilla developer documentation.

Hiding buttons

If you have a lot of buttons, you might way to minimize the cognitive load of the wizard by only showing the absolutely necessary buttons (more on this in the below section). For this purpose, you might want to hide buttons that are assigned a key, which you can do with the visible parameter: onButton("myKeyboardOnlyButton", key = "e", visible = true).

Customizing the wizard interface

For a skill that you aim to control through wizarding, it is crucial that you design a wizard button configuration that reduced the cognitive load of the wizard. In other words, the wizard needs to know what buttons are where on the screen, as well as know what happens when each button is pressed. If not, you risk disrupting the flow of the interaction, or stress the Wizard into pressing the wrong buttons. Thus, spending time designing the wizard interface is usually a good investment for your skill project!

We support several ways of structuring wizard-buttons for the built-in Wizard page (in the web interface):

  1. Through state inheritance. Buttons will end up in vertical sections with the state name displayed on the wizard page.
  2. Through assigning sections to buttons. Each button has an optional section parameter that can have values Left and Right (it defaults to Left). The vertical sections defined in 1) will then be respected in both sections that has buttons.
  3. Through overriding buttons. If you have a button that starts and ends an interaction, you can use the same id for the buttons but have different labels depending on if you are in an active or a passive state.
  4. Through customizing the color and size of buttons, e.g.: onButton("Big green button", color = Color.Green, size = Size.Large).