Adaptive expressions

APPLIES TO: SDK v4

Bots use adaptive expressions to evaluate the outcome of a condition based on runtime information available in memory to the dialog or the Language Generation system. These evaluations determine how your bot reacts to user input and other factors that impact bot functionality.

Adaptive expressions address this core need by providing an adaptive expression language that can be used with the Bot Framework SDK and other conversational AI components, like Bot Framework Composer, Language Generation, Adaptive dialogs, and Adaptive Cards templating.

An adaptive expression can contain one or more explicit values, prebuilt functions, or custom functions. Consumers of adaptive expressions also have the capability to inject additional supported functions. For example, all language generation templates are available as functions as well as additional functions that are only available within that component's use of adaptive expressions.

Operators

Adaptive expressions support the following operator types and expression syntax:

  • arithmetic
  • comparison
  • logical
  • other operators and expressions syntax
Operator Functionality Prebuilt function equivalent
+ Addition. Example: A + B add
- Subtraction. Example: A - B sub
unary + Positive value. Example: +1, +A N/A
unary - Negative value. Example: -2, -B N/A
* Multiplication. Example: A * B mul
/ Division. Example: A / B div
^ Exponentiation. Example: A ^ B exp
% Modulus. Example: A % B mod

Variables

Variables are always referenced by their name in the format ${myVariable}. They can be referenced either by the property selector operator in the form of myParent.myVariable, using the item index selection operator like in myParent.myList[0], or by the getProperty() function.

There are two special variables. [] represents an empty list, and {} represents a empty object.

Explicit values

Explicit values can be enclosed in either single quotes 'myExplicitValue' or double quotes "myExplicitValue".

Functions

An adaptive expression has one or more functions. For more information about functions supported by adaptive expressions, see the prebuilt functions reference article.

Bot Framework Composer

Bot Framework Composer is an open-source visual authoring canvas for developers and multidisciplinary teams to build bots. Composer uses adaptive expressions to create, calculate, and modify values. Adaptive expressions can be used in language generation template definitions and as properties in the authoring canvas. As seen in the example below, properties in memory can also be used in an adaptive expression.

The expression (dialog.orderTotal + dialog.orderTax) > 50 adds the values of the properties dialog.orderTotal and dialog.orderTax, and evaluates to True if the sum is greater than 50 or False if the sum is less than 50.

Read Conversation flow and memory for more information about how expressions are used in memory.

Language generation

Adaptive expressions are used by language generation (LG) systems to evaluate conditions described in LG templates. In the example below, the join prebuilt function is used to list all values in the recentTasks collection.

# RecentTasks
- IF: ${count(recentTasks) == 1}
    - Your most recent task is ${recentTasks[0]}. You can let me know if you want to add or complete a task.
- ELSEIF: ${count(recentTasks) == 2}
    - Your most recent tasks are ${join(recentTasks, ', ', ' and ')}. You can let me know if you want to add or complete a task.
- ELSEIF: ${count(recentTasks) > 2}
    - Your most recent ${count(recentTasks)} tasks are ${join(recentTasks, ', ', ' and ')}. You can let me know if you want to add or complete a task.
- ELSE:
    - You don't have any tasks.

Read the using prebuilt function in variations section of the .lg file format article for more information.

Adaptive Cards templating

Adaptive Cards templating can be used by developers of bots and other technologies to separate data from the layout in an Adaptive Card. Developers can provide data inline with the AdaptiveCard payload, or the more common approach of separating the data from the template.

For example, say you have the following data:

{
    "id": "1291525457129548",
    "status": 4,
    "author": "Matt Hidinger",
    "message": "{\"type\":\"Deployment\",\"buildId\":\"9542982\",\"releaseId\":\"129\",\"buildNumber\":\"20180504.3\",\"releaseName\":\"Release-104\",\"repoProvider\":\"GitHub\"}",
    "start_time": "2018-05-04T18:05:33.3087147Z",
    "end_time": "2018-05-04T18:05:33.3087147Z"
}

The message property is a JSON-serialized string. To access the values within the string, the json prebuilt function can be called:

{
    "type": "TextBlock",
    "text": "${json(message).releaseName}"
}

And will result to the following object:

{
    "type": "TextBlock",
    "text": "Release-104"
}

For more information and examples see the adaptive cards templating documentation.

Additional resources