Rendering Responses

Conversations are primarily driven by an Assistant’s response to the user. Responses not only present the user with the outcome with of the tiggered action, but also control the dialogue by instigating the user to provide intents in a logical manner.

Flask-Assisant provides three primary response types as well as platform-specific rich message types.

Primary Types

The primary responses include ask, tell, and event. All rich messages extend the ask and tell constructs.

To import the repsonse types:

from flask_assistant import ask, tell, event, build_item

ask

To ask a question which expects a response from the user:

@assist.action('Kickit')
def kick_it():
    return ask('Can I kick it?')

tell

To return a text/speech response to the user and end the session:

@assist.action('Answer')
def answer():
    return tell('Yes you can!')

event

To invoke another intent directly and bypass an exchange with the user, an event can be triggered.

Assuming the intent “GoOnThen” contains an event named “first_verse”, triggering the “Begin” intent will provide the user with the question “‘Before this, did you really know what life was?”

@assist.action('GoOnThen')
def first_verse():
    return ask('Before this, did you really know what life was?')

@assist.action('Begin')
def start_verse():
    return event('first_verse')

Note

The name of an intent’s action function does not necessarily need to share the name of the intent’s event, though it may often make sense and provide a cleaner representation of dialogue structure.

Currently, Events must be defined within an Intent in the Dialogflow console. But support for event definitions is coming soon

Rich Messages

In addidtion to the primary text/speech responses, Flask-Assistant plans to provide Rich Messages for various platforms.

Currently, Rich Messages are only support for Actions on Google.

Rich Messages for Actions on Google

By utlizing the following rich responses, an Assistant can easily integreate with Actions on Google and provide a greater experience on devices that support Google Assistant (Google Home and mobile phones).

To enable Actions on Google Integration:

app.config['INTEGRATIONS'] = ['ACTIONS_ON_GOOGLE']

Displaying a Card

Use a Card to present the user with summaries or concise information, and to allow users to learn more if you choose (using a weblink).

  • Image
  • Title
  • Sub-title
  • Text body
  • Link

The only information required for a card is the text paramter which is used to fill the text body.

@assist.action('ShowCard')
def show_card():

    resp = ask("Here's an example of a card")

    resp.card(text='The text to display',
              title='Card Title',
              img_url='http://example.com/image.png'
              )

    return resp

Suggesting Other Intents

Provide the user with a Suggestion Chip to hint at responses to continue or pivot the conversation. The suggestion text is sent as a query to Dialogflow when selected and therefore should match a User Says phrase for the intent to be triggered.

So given the following intents:

HelpIntent:
  UserSays:
  - Get Help
  - help

Restart:
  Usersays:
  - start over

GetArtistInfo:
  Usersays:
  - radiohead
  - violent femmes
  - the books

  Annotations:
  - radiohead: artist
  - 'the books': artist

Provide suggestions for likely intents:

@assist.action('SuggestThings')
def suggest_things():
    return ask('What's up?').suggest('help', 'start over', 'radiohead')

Linking to External Resources

In addition to suggestion chips for guiding dialogue, link_out chips can be used to send the user to external URLS.

@assist.action('ShowResources')
def link_resources():
    resp = ask('Need some external help?')

    resp.link_out('Github Repo', 'https://github.com/treethought/flask-assistant')
    resp.link_out('Read The Docs', 'http://flask-assistant.readthedocs.io/en/latest/')

List Selectors

Lists present the user with a vertical list of multiple items and allows the user to select a single one. Selecting an item from the list generates a user query (chat bubble) containing the title of the list item. This user query will be used to match an agent’s intent just like any other query.

Note

There seems to be a discrepency bewteen Dialogflow and Actions on Google in regards to the selection of list items. Within the Dialogflow console, the items key is sent as the user query. However, Actions on Google sends the item’s title.

For proper results within both platforms, simply provide both the item’s key and title as User Says phrase until the issue is resolved.

First, create primary response

@assist.action('ShowList')
def action_func():

    # Basic speech/text response
    resp = ask("Here is an example list")

Then create a list with a title and assign to variable

# Create a list with a title and assign to variable
mylist = resp.build_list("Awesome List")

Add items directly to list

mylist.add_item(title="Option 1", # title sent as query for Actions
                key="option_1",
                img_url="http://example.com/image1.png",
                description="Option 1's short description",
                synonyms=['one', 'number one', 'first option'])

mylist.add_item(title="Option 2",
                key="option_2",  # key sent as query for Dialogflow
                img_url="http://example.com/image2.png",
                description="Option 2's short description",
                synonyms=['two', 'number two', 'second option'])

Or build items independent of list and add them to the list later

new_item = build_item(title="Option 3",
                      key="option_3",  # key sent as query for Dialogflow
                      img_url="http://example.com/image3.png",
                      description="Option 3's short description",
                      synonyms=['three', 'number three', third option'])

mylist.include_items(new_item)

return mylist

Warning

Creating a list with build_list returns an instance of a new response class. Therfore the result is a serpeate object than the primary response used to call the build_list method.

The original primary response (ask/tell) object will not contain the list, and so the result should likely be assigned to a variable.

Carousels

Carousels scroll horizontally and allows for selecting one item. They are very similar to list items, but provide richer content by providing multiple tiles resembling cards.

To build a carousel:

@assist.action('FlaskAssistantCarousel')
def action_func():
    resp = ask("Here's a basic carousel").build_carousel()

    resp.add_item("Option 1 Title",
                  key="option_1",
                  description='Option 1's longer description,
                  img_url="http://example.com/image1.png")

    resp.add_item("Option 2 Title",
                  key="option_2",
                  description='Option 2's longer description,
                  img_url="http://example.com/image2.png")
    return resp