18 Entities

While intents map words and phrases to a specific action, entities add context to the intent itself. They help to describe the intent more fully and enable your bot to complete a user request.

The OrderPizza intent, for example, describes a user request, but only in general terms. To fill in the specifics, this intent is augmented by the PizzaSize entity, which identifies values like large, medium, and small from the user input. There are two types of entities, both of which you can declare as variables in the dialog flow: built-in entities that we provide for you and custom entities, which you can add on your own.

Built-In Entities

We provide entities that identify objective information from the user input, like time, date, and addresses. These built-in entities are divided into two groups: simple entities that extract primitive values like strings and integers, and complex entities that detect values from the user input using groups of properties.

Whenever you define a variable as an entity in your dialog flow, be sure to match the entity name and letter case exactly. In other words, you’ll get a validation error if you enter confirm: "YESNO" instead of confirm: “YES_NO”.

Simple Entities

Entity Name Content Identified Examples
NUMBER Matches ordinal and cardinal numbers. You can resolve a entity as the locale-specific format (grouping of thousands by full stops, commas, spaces, etc.).
  • 1st

  • first

  • 1

  • one

EMAIL An email address. The NLU system can recognize email addresses that have a combination of the following:
  • part before the at (@) symbol:
    • uppercase and lowercase letters in the Latin alphabet (A-Z and a-z)
    • digits (0-9)
    • the following printable characters: !#$%&'*+-/=?^_`{}~
    • dot (.)
  • part after the at (@) symbol:
    • uppercase and lowercase letters in the Latin alphabet (A-Z and a-z)
    • digits (0-9)
    • hyphen (-)
YES_NO Detects a “yes” or “no”. Yes, Yeah, no

Complex Entities

Unlike simple entities, complex entities extract content using properties, each of which recognizes a specific value. You can see these properties in the Tester. The JSON output that’s returned by the NLU Engine shows these entities along with the value that they’ve identified from the user input. Within your dialog flow definition, you can use these properties to isolate a specific facet of an entity value.

Entity Name Content Extracted Examples Properties (Referenced in Value Expressions) Example NLU Engine Response
ADDRESS The city, house number, and road 500 Smith Road, Smithville
  • city

  • houseNumber

  • road

  • originalString

"road": "smith road",
"city": "smithville",
"entityName": "ADDRESS",
"houseNumber": "500",
"originalString": "500 Smith Road, Smithville"
DATE An absolute or relative date.
Note: When the user input names a day, but provides no other temporal context, the system considers this a future date. For example, it considers Wednesday in the following input as next Wednesday, not the current Wednesday or the prior Wednesday.
  • Book me a ticket for Wednesday.

  • I want to file an expense report for Wednesday.

You can override thie behavior by applying an ambiguity resolution rule. While the DATE entity resolves to format of several supported locales, you can opt to ignore the format of the detected locale, and impose a default format and a tense (future, past, nearest, etc.) by applying an ambiguity resolution rule.
  • November 9, 2016

  • Today

  • originalString

  • date

"date" : 1539734400000,
"entityName" : "DATE"
"orginalString" : Wednesday, "October 17, 2018"
TIME A specific time. In some cases, for example, when the input is ambiguous, you may need the TIME entity to resolve input consistently as a past or future time, or approximate it by the nearest time. To do this, apply an ambiguity resolution rule. 2:30 pm
  • hrs

  • mins

  • secs

  • "hourFormat":"PM"

"startTime": { "date": 1613653200000, "zoneOffset": "0", "endOffset": 4, "mins": 0, "zone": "UTC", "entityName": "TIME", "secs": 0, "hrs": 1, "originalString": "1 pm", "type": "TIME", "hourFormat": "PM", "beginOffset": 0 }
DURATION The amount of time between the two endpoints of a time interval
  • 4 years

  • two weeks

  • startDate

  • endDate

  • originalString
{ "startDate":1482019200000, "endDate":1482623999999, "entityName":"DURATION" }
CURRENCY Representations of money. You can disambiguate dollar and yen currencies by the detected locale of the user.
  • $67

  • 75 dollars

  • amount

  • currency

  • totalCurrency

{ "amount":50, "currency":"dollar", "total_currency":"50.0 dollar", "entityName":"CURRENCY" }
PHONE NUMBER A phone number—The NLU Engine recognizes phone numbers that have seven or more digits (it can’t recognize any phone number with fewer digits). All country codes need to be prefixed with a plus sign (+), except for the United States of America (where the plus sign is optional). The various parts of the phone number (the area code, prefix, and line number), can be separated by dots (.), dashes (-), or spaces. If there are multiple phone numbers entered in the user input, then the NLU Engine can recognize them when they’re separated by commas. It can’t recognize different phone numbers if they’re separated by dots, dashes or spaces.
  • (650)-555–5555

  • 16505555555

  • +61.3.5555.5555

  • phoneNumber

  • completeNumber

{ "phone_number":"(650)-555-5555", "complete_number":"(650)-555-5555", "entityName":"PHONE_NUMBER" }
URL A URL—This entity can extract IPv4 addresses, Web URLs, deep links (http://example.com/path/page), file paths, and mailto URIs. If the user input specifies login credentials, then it must also include the protocol. Otherwise, the protocol isn’t required. http://example.com
  • protocol

  • domain

  • fullPath

PERSON Recognizes the first, middle, and last names of people, including fictional characters.

The PERSON entity can't match names that are also locations (for example, Virginia North).

To expand the PERSON entity to always match the people in your organization, you can associate it with a Value List Entity.
  • John J. Jones
  • Ashok Kumar
  • Gabriele D'Annunzio
  • Jones, David
  • Cantiflas
  • Zhang San
  • Virginia Jones
  • originalString

  • name

"PERSON": [ { "originalString": "John J. Johnson", "name": "john j. johnson", "entityName": "PERSON" } ]

Ambiguity Resolution Rules for Times and Dates


Users can enter partial dates where the actual time is implied. For example:
  • "Schedule a meeting for Monday"
  • "Create an expense report for 7/11"
  • "Create an expense report for the 11th"
Some situations, like scheduling a meeting, imply a future time. Others, like creating an expense report, refer to some time in the past. To ensure that the TIME or DATE entities can resolve ambiguous input as the past, present, or as the closest approximation, you can apply Ambiguity Resolution Rules.
Resolution Rules for DATE


Rule How it works Examples
Past Resolves the ambiguous input as the nearest day of the week in the past.
  • If the utterance includes "Monday" and the current day is also Monday, then "Monday" is resolved as Today.
  • If the utterance includes "Monday" and the current day is Wednesday, the "Monday" is resolved as the previous Monday.
Future Resolves the ambiguous input as the nearest day in the future
  • If the utterance includes 'Monday" and the current day is also Monday, then "Monday" is resolved as TODAY.
  • If the utterance includes "Monday", and the current day is Tuesday, then "Monday" is resolved as the following Monday.
  • If the utterance includes "Tuesday", and the current day is Monday, then "Tuesday" is resolved as this Tuesday.
Nearest Resolves the ambiguous input as the nearest day.
  • If the utterance includes "Monday"and the current day is also Monday, the "Monday" is resolved as TODAY.
  • If the utterance includes "Monday" and the current day is Tuesday, then "Monday" resolves as yesterday.
  • If the utterance includes "Monday", and the current day is Sunday, the "Monday" resolves as Tomorrow.
Default Resolves the ambiguous input as a future date. For example, if the input include Wednesday, the day is interpreted as next Wednesday, not the prior Wednesday or the current day (if it's a Wednesday, that is).
Resolution Rules for TIME


You can set the temporal context for the time resolution for the TIME entity by applying the resolution rules. To access this option, click the TIME entity to open the configuration page.

Rule How it works Examples
PAST Resolves the input to the nearest time in the past relative to the current time in the UTC time zone.
  • If the utterance includes "9 am" and the current time is 10:00 am, then the time is resolved as 9:00 am today.
  • If the utterance includes "9 pm" and the current time is 10:00 am, then the time is resolved as 9:00 pm yesterday.
  • If the utterance includes "9" and the current time is 10:00 am, then the time is resolved as 9:00 am today.
Future Resolves the input to the nearest time in the future relative to the current time in the UTC time zone.
  • If the utterance includes "9 am" and the current time right now is 10:00 am, then the time is resolved as 9:00 am tomorrow.
  • If the utterance includes "9 pm" and the current time is 10:00 am, the time is resolved as 9 pm today.
  • If the utterance includes "9" and the current time is 10:00 am, then the time is resolved as 9:00 pm today.
Nearest Resolves the input as the nearest time relative to the current time in the UTC time zone.
  • If the utterance includes "9 am" and the current time is 10:00 am, then the time is resolved as today 9:00 am.
  • If the utterance includes "9 pm" and the current time is 10:00 am, then the time is resolved as 9:00 pm today.
  • If the utterance includes"9" and the current time is 10:00 am, then the time is resolved as 9:00 am today.
  • If the utterance includes "10:00" and the current time is 1:00 am, then the time is resolved as 10:00 pm yesterday.
Default Resolves the input by the method used in the pre-21.06 releases of Oracle Digital Assistant. Examples:
  • If the utterance includes is "9 am" and the current time is 10 am, then the time is resolved as 9 am today.
  • If the utterance includes "9 pm" and the current time is 10 am, then the time is resolved as 9 pm today.
  • If the utterance includes "9" and the current time is 10 am, then the time is resolved as 9 am today.
  • If the utterance includes "1:00 am" and the current time is 2 pm, then the time is resolved as 1 am tomorrow.

Locale-Based Entity Resolution


You can enable the CURRENCY, DATE and NUMBER entities to resolve to the user locale by switching on Consider End User Locale. Depending on the entity, this option has different applications:
  • DATE resolves to the locale-specific format: it can resolve 11/7 as November 7 for en-US or July 11 for en-AU, for example. For non-supported locales, you can apply a format and a temporal context, such as past or future.
  • NUMBER resolves to the country-specific numeric format -- the comma, period, or space used to separate groups of thousands and the decimal point with or without a thin space that separates the fractional part of the number. For example, the U.K. and U.S. both use a comma to separate groups of thousands, Italy uses a period, and France groups thousands with a space.
  • CURRENCY disambiguates different currencies for dollars ($) and yen (¥).
Locale-Based Date Resolution


For this Locale This Input... Resolves As... Format (Date-Month Sequence)
en-US (United States) 11/7 November 7 MONTH_DAY
en-GB (Great Britain) 11/7 July 11 DAY_MONTH
en-CA (Canada) 11/7 November 7 MONTH_DAY
fr-CA (Canada) 11/7 November 7 MONTH_DAY
en-AU (Australia) 11/7 July 11 DAY_MONTH
en-MX (Mexico) 11/7 July 11 DAY_MONTH
en-SG (Singapore) 11/7 July 11 DAY_MONTH
en-AE (United Arab Emirates) 11/7 November 7 MONTH_DAY
en-AR (Arabic) 11/7 November 7 MONTH_DAY
en-FR (France) 11/7 July 11 DAY_MONTH
en-NL (Netherlands) 11/7 July 11 DAY_MONTH
en-DE (Germany) 11/7 July 11 DAY_MONTH
en-IT (Italy) 11/7 July 11 DAY_MONTH
en-PT (Portugal) 11/7 July 11 DAY_MONTH
en-ES (Spain) 11/7 July 11 DAY_MONTH
en-CN (China) 11/7 November 7 MONTH_DAY
en-JP (Japan) 11/7 November 7 MONTH_DAY
Locale-Based Currency Resolution


The CURRENCY entity can disambiguate between different dollar ($) and yen (¥) currencies when the user's locale is detected and when you switch on Consider End User Locale. When no locale is detected, you can set the input to resolve as a specific currency. You can access these options by selecting the CURRENCY entity.

For this Locale This Input... Resolves as (Dollar Ambiguity) This Input... Resolves as (Yen Ambiguity)
en-US (United States) 20 dollars 20.0 USD 20 ¥ 20.0 JPY
en-GB (Great Britain) 20 dollars 20.0 USD 20 ¥ 20.0 JPY
en-CA (Canada) 20 dollars 20.0 CAD 20 ¥ 20.0 JPY
fr-CA (Canada) 20 dollars 20.0 CAD 20 ¥ 20.0 JPY
en-AU (Australia) 20 dollars 20.0 AUD 20 ¥ 20.0 JPY
en-MX (Mexico) 20 dollars 20.0 MXN 20 ¥ 20.0 CNY
en-SG (Singapore) 20 dollars 20.0 SGD 20 ¥ 20.0 JPY
en-AE (United Arab Emirates) 20 dollars 20.0 USD 20 ¥ 20.0 JPY
en-AR (Arab) 20 dollars 20.0 USD 20 ¥ 20.0 JPY
en-FR (France) 20 dollars 20.0 USD 20 ¥ 20.0 JPY
en-NL (Netherlands) 20 dollars 20.0 USD 20 ¥ 20.0 JPY
en-DE (Germany) 20 dollars 20.0 USD 20 ¥ 20.0 JPY
en-IT (Italy) 20 dollars 20.0 USD 20 ¥ 20.0 JPY
en-PT (Portugal) 20 dollars 20.0 USD 20 ¥ 20.0 JPY
en-ES (Spain) 20 dollars 20.0 USD 20 ¥ 20.0 JPY
en-CN (China) 20 dollars 20.0 USD 20 ¥ 20.0 CNY
en-JP (Japan) 20 dollars 20.0 USD 20 ¥  
Locale-Based Number Resolution


For this Locale This Input... Resolves As... Number Format
en-US (United States) 100000000 1,000,000.00 COMMA_DOT
en-GB (Great Britain) 100000000 1,000,000.00 COMMA_DOT
en-CA (Canada) 100000000 1,000,000.00 COMMA_DOT
fr-CA (Canada) 100000000 1.000.000,00 DOT_COMMA
en-AU (Australia) 100000000 1,000.000 .00 COMMA_DOT SPACE_DOT
en-MX (Mexico) 100000000 1,000,000.00 COMMA_DOT
en-SG (Singapore) 100000000 1,000,000.00 COMMA_DOT
en-AE (United Arab Emirates) 100000000 1.000.000,00 DOT_COMMA
en-AR (Arab) 100000000 1.000.000,00 DOT_COMMA
en-FR (France) 100000000 1 000 000 .00 SPACE_COMMA SPACE_DOT
en-NL (Netherlands) 100000000 1.000.000,00 DOT_COMMA
en-DE (Germany) 100000000 1.000.000,00 DOT_COMMA
en-IT (Italy) 100000000 1.000.000,00 DOT_COMMA
en-PT (Portugal) 100000000 1 000 000 .00 SPACE_COMMA SPACE_DOT
en-ES (Spain) 100000000 1.000.000,00 DOT_COMMA
en-CN (China) 100000000 1,000,000.00 COMMA_DOT
en-JP (Japan) 100000000 1,000,000.00 COMMA_DOT

Custom Entities

Because the built-in entities extract generic information, they can be used in a wide variety of bots. Custom entities, on the other hand, have a narrower application. Like the FinancialBot’s AccountType entity that enables various banking transactions by checking the user input for keywords like checking, savings, and credit cards, they’re tailored to the particular actions that your bot performs.

Composite Bag

A composite bag is a grouping of related entities that can be treated as a whole within a conversation. Using composite bags enables a skill to extract values for multiple entities in one user utterance, which allows a conversation to flow more naturally. Early on in the designing of your skill, you should identify these groups of related entities, which often reflect clear business domains, and build composite bags for them.

For example, a composite bag for a pizza might include entities for type, size, crust, and extra toppings. If a user enters "I'd like a large pepperoni pizza with a gluten-free crust", the skill could extract "large", "pepperoni", and "gluten-free" from that input and not need to prompt the user for those values individually.

You can configure the composite bag entity to resolve its constituent items in different ways: it can prompt for individual entity values when they're missing from the user input, for example, or it can use the value extracted by one if its entities to resolve a second entity.

Composite bags can also include other types of items, such as those that store location and accept free text and attachments.

See Composite Bag Entities for details on creating and configuring composite bags.

ML Entities


An ML (machine learning) entity identifies an entity value based on the wording of the user input, not the entity value itself. You create an ML Entity from training utterances, much in the same way that you'd create an intent. After you train the entity, it can interpret the context of a message and generalize entity values. This flexible "fill-in-the-blanks" approach allows an ML entity to recognize values even when they're not included in the training set.

Because anticipating the format or wording of user messages is challenging, especially for multi-lingual skills, you may want to use an ML entity in place of the less flexible Value List and Regular Expression entities. Despite fuzzy matching, Value List entities (both static and dynamic) can often detect entity values only when they match their values or synonyms. "Computer engineer" might not match "computer engineering", for example. Regular Expression entities restrict the user input to matching a predetermined pattern or the wording that proceeds or follows an entity value. ML entities, on the other hand, are adaptable and can be made more so through robust training data.

Value List Entities

An entity based on a list of predetermined values, like menu items that are output by the System.List component. You can optimize the entity’s ability to extract user input by defining synonyms. These can include abbreviations, slang terms, and common misspellings. Synonym values are not case-sensitive: USA and usa, for example, are considered the same value.

Dynamic Entities

Dynamic entities are entities whose values can be updated even after a skill has been published.


Dynamic entities are only supported on instances of Oracle Digital Assistant that were provisioned on Oracle Cloud Infrastructure (sometimes referred to as the Generation 2 cloud infrastructure). If your instance is provisioned on the Oracle Cloud Platform (as are all version 19.4.1 instances), then you can't use this feature.
Like value list entities, dynamic entities are enum types. However, dynamic entities differ from value list entities in that their values are not static; they may be subject to frequent change. Because of this – and also because dynamic entities can contain thousands of values and synonyms – the values are not usually managed in the UI. They are instead managed by the Dynamic Entities API (described in REST API for Oracle Digital Assistant).


Enhanced speech models created for dynamic entity values are currently trained only after a finalized push request is made from the Dynamic Entity API, so if you change dynamic entity values through the UI, the change won't be included in the enhanced speech models after you retrain the skill. Your changes can only be included after the next update from the API. To preserve your changes, the request's copy parameter must be set to TRUE.

Regular Expression

Resolves an entity using a regular expression (regex), such as (?<=one\s).*(?=\sthree). Regular expressions allow your skill to identify pre-defined patterns in user input, like ticket numbers. Unlike the other entity types, regex-based entities don’t use NLP because the matching is strictly pattern-based.

Entity List

A super set of entities. Using a travel skill as an example, you could fold the entities that you’ve already defined that extract values like airport codes, cities, and airport names into a single entity called Destination. By doing so, you would enable your skill to respond to user input that uses airport codes, airport names, and cities interchangeably. So when a user enters “I want to go to from JFK to San Francisco,” the Destination entity detects the departure point using the airport code entities and the destination using the cities entity.


A derived entity is the child of a built-in entity or another entity that you define. You base this relationship on prepositional phrases (the "to" and "from" in utterances like I want to go from Boston to Dallas or Transfer money from checking to savings). Derived entities can’t be parent entities. And because the NLU Engine detects derived entities only after it detects all of the other types of entities, you can’t add derived entities as members of an entities list.

Create Entities

To create an entity:
  1. Click Entities (This is an image of the Entities icon.) in the side navbar.
  2. Click Add Entity and then enter the name and select the type. The dialog's fields reflect the entity type. For example, For regular expressions entities, you can add the expression. For Value List entities, you add the values and synonyms.
    If your skill supports multiple languages through Digital Assistant's native language support, then you need to add the foreign-language counterparts for the Value List entity's values and synonyms.

    Because these values need to map to the corresponding value from the primary langauge (The Primary Language Value), you need to select the primary value before you add its secondary language counterpart. For example, if you've added French as a secondary language to a skill's whose primary language is English, you first select small as the Primary Language Value and then add petite.

  3. As an optional step, enter a description. You might use the description to spell out the entity, like the pizza toppings for a PizzaTopping entity. This descripition is not retained when you add the entity to a composite bag.
  4. You can add the following functions, which are optional. They can be overwritten if you add the entity to a composite bag.
    • If a value list entity has a long list of values, but you only want to show users only a few options at a time, you can set the pagination for these values by entering a number in the Enumeration Range Size field, or by defining an Apache FreeMarker expression that evaluates to this number. For example, you can define an expression that returns enum values based on the channel.

      When you set this property to 0, the skill won't output a list at all, but will the user input against an entity value.

      If you set this number to one lower than the total number of values defined for this entity, then the System.resolveEntities component displays a Show More button to accompany each full set of values. If you use the System.CommonResponse component to resolve the entity, then you can configure the Show More button yourself.
      This is an image of the Show More button.
      You can change the Show More button text using the showMoreLabel property that belongs to the System.ResolveEntities and the System.CommonResponse component.

    • Add an error message for invalid user input. Use an Apache FreeMarker expression that includes the system.entityToResolve.value.userInput property. For example, ${system.entityToResolve.value.userInput!'This'}' is not a valid pizza type.
    • To allow users to pick more than one value from a value list entity, switch on Multiple Values. When you switch this on, the values display as a numbered list.
      This is an image of the numbered multi-value list.
      Switching this option off displays the values as a list of options, which allows only a single choice.
    • Switching on Fuzzy Match increases the chances of the user input matching a value, particularly when your values don’t have a lot of synonyms. Switching this off enforces strict matching, meaning that the user input must be an exact match to the values and synonyms; “cars” won’t match a value called “car”, nor will “manager” match a “development manager” value.
    • For skills that are configured with a translation service, entity matching is based on the translation of the input. If you switch on Match Original Value, the original input is also considered in entity matching, which could be useful for matching values that are untranslatable.
    • To force a user to select a single value, switch on Prompt for Disambiguation and add a disambiguation prompt. By default, this message is Please select one value of <item name>, but you can replace this with one made up solely of text (You can only order one pizza at a time. Which pizza do you want to order?) or a combination of text and FreeMarker expressions. For example:
      "I found multiple dates: <#list system.entityToResolve.value.disambiguationValues.Date as date>${date.date?number_to_date}<#sep> and </#list>. Which date should I use as expense date?"
    • Define a validation rule using a FreeMarker expression.


      You can only add prompts, disambiguation, and validation for built-in entities when they belong to a composite bag.
  5. Click Create.
  6. Next steps:
    1. Add the entity to an intent. This informs the skill of the values that it needs to extract from the user input during the language processing. See Add Entities to Intents.
    2. In the dialog flow, declare a context variable for the entity.
    3. Access the variable values using Apache FreeMarker expressions. See Built-In FreeMarker Array Operations.
    4. Click Validate and review the validation messages for errors related to entity event handlers (if used), potential problems like multiple values in a value list entity sharing the same synonym, and for guidance on applying best practices such as adding multiple prompts to make the skill more engaging.
Value List Entities for Multiple Languages

When you have a skill that is targeted to multiple languages and which uses Digital Assistant's native language support, you can set values for each language in the skill. For each entity value in a skill's primary language, you should designate a corresponding value in each additional language.

Create ML Entities


ML Entities are a model-driven approach to entity extraction. Like intents, you create ML Entities from training utterances – likely the same training utterances that you used to build your intents. For ML Entities, however, you annotate the words in the training utterances that correspond to an entity value.

To get started, you can annotate the training data yourself, but as is the case for intents, you can develop a more varied (and therefore robust) training set by crowd sourcing it. Also, if the intent training data is already expansive, then you may want to crowd source it rather than annotate each utterance yourself. With the annotations complete, you then train the model, then test it. After reviewing the entities detected in the test runs, you can continue to update the corpus and retrain to improve the accuracy.

To create an ML Entity:
  1. Click +Entity.
  2. Complete the Create Entity dialog. Keep in mind that the Name and Description appear in the crowd worker pages for Entity Annotation Jobs.
    • Enter a name that identifies the annotated content. A unique name helps crowd workers.
    • Enter a description. Although this an optional property, crowd workers use it, along with the Name property, to differentiate entities.
  3. Click Create.
  4. Click +Value List Entities to associate this entity with up to five Value List Entities. This is optional, but associating an ML Entity with a Value List Entity combines the contextual extraction of the ML Entity and the context-agnostic extraction of the Value List Entity.
  5. Associate the ML Entity with an intent.
  6. Click the DataSet tab. This page lists all of the utterances for each ML Entity in your skill, which include the utterances that you've added yourself to bootstrap the entity, those submitted from crowd sourcing jobs, or have been imported as JSON objects. From this page, you can add utterances manually or in bulk by uploading a JSON file. You can also manage the utterances from this page by editing them (including annotating or re-annotating them), or by deleting, importing, and exporting them.
    • Add utterances manually:
      • Click Add Utterance. After you've added the utterance, click Edit Annotations to open the Entity List.


        You can only add one utterance at a time. If you want to add utterances in bulk, you can either add them through an Entity Annotation job, or you can upload a JSON file.
      • Highlight the text relevant to the ML Entity, then complete the labeling by selecting the ML Entity from the Entity List. You can remove an annotation by clicking x in the label.
        This is an image of the Delete icon on an annotation.

    • Add utterances from a JSON file. This JSON file contains a list of utterance objects.
          "Utterance": {
            "utterance": "I expensed $35.64 for group lunch at Joe's on 4/7/21",
            "languageTag": "en",
            "entities": [
                "entityValue": "Joe's"   
                "entityName": "VendorName",
                "beginOffset": 37,
                "endOffset": 42
          "Utterance": {
            "utterance": "Give me my $30 for Coffee Klatch on 7/20",
            "languageTag": "en",
            "entities": [
                "entityName": "VendorName",
                "beginOffset": 19,
                "endOffset": 32
      You can upload it by clicking More > Import to retrieve it from your local system.
      The entities object describes the ML entities that have been identified within the utterance. Although the preceding example illustrates a single entities object for each utterance, an utterance may contain multiple ML entities which means multiple entities objects:
          "Utterance": {
            "utterance": "I want this and that",
            "languageTag": "en",
            "entities": [
                "entityName": "ML_This",
                "beginOffset": 7,
                "endOffset": 11
                "entityName": "ML_That",
                "beginOffset": 16,
                "endOffset": 20
      entityName identifies the ML Entity itself and entityValue identifies the text labeled for the entity. entityValue is an optional key that you can use to validate the labeled text against changes made to the utterance. The label itself is identified by the beginOffset and endOffset properties, which represent the offset for the characters that begin and end the label. This offset is determined by character, not by word, and is calculated from the first character of the utterance (0-1).
      If you don't want to determine the offsets, you can leave the entities object undefined and then apply the labels after you upload the JSON file.
          "Utterance": {
            "utterance": "I expensed $35.64 for group lunch at Joe's on 4/7/21",
            "languageTag": "en",
            "entities": []
          "Utterance": {
            "utterance": "Give me my $30 for Coffee Klatch on 7/20",
            "languageTag": "en",
            "entities": []
      The system checks for duplicates to prevent redundant entries. Only changes made to the entities definition in the JSON file are applied. If an utterance has been changed in the JSON file, then it's considered a new utterance.
    • Edit an annotated utterance:
      • Click Edit This is an image of the Edit icon. to remove the annotation.


        A modified utterance is considered a new (unannotated) utterance.
      • Click Edit Annotations to open the Entity List.
      • Highlight the text, then select an ML Entity from the Entity List.
      • If you need to remove an annotation, click x in the label.
  7. When you've completed annotating the utterances. Click Train to update both trainer Tm and the Entity model.
  8. Test the recognition by entering a test phrase in the Utterance Tester, ideally one with a value not found in any training data. Select Label View and then check the results to find out if the model detected the correct ML Entity and if the text has been labeled correctly and completely.
Import Value List Entities from a CSV File

Rather than creating your entities one at a time, you can create entire sets of them when you import a CSV file containing the entity definitions.

This CSV file contains columns for the entity name, (entity), the entity value (value) and any synonyms (synonyms). You can create this file from scratch, or you can reuse or repurpose a CSV that has been created from an export.

Whether you're starting anew or using an exported file, you need to be mindful of the version of the skill that you're importing to because of the format and content changes for native language support that were introduced in Version 20.12. Although you can import a CSV from a prior release into a 20.12 skill without incident in most cases, there are still some compatibility issues that you may need to address. But before that, let's take a look at the format of a pre-20.12 file. This file is divided into the following columns: entity, value, and synonyms. For example:
For skills created with, or upgraded to, Version 20.12, the import files have language tags appended to the value and synonyms column headers. For example, if the skill's primary native language is English (en), then the value and synonyms columns are en:value and en:synonyms:
PizzaSize,Extra Large,XL
CSVs that support multiple native languages require additional sets of value and synonyms columns for each secondary language. If a native English language skill's secondary language is French (fr), then the CSV has fr:value and fr:synonyms columns as counterparts to the en columns:
PizzaSize,Extra Large,XL,pizza extra large,
Here are some things to note if you plan to import CSVs across versions:
  • If you import a pre-20.12 CSV into a 20.12 skill (including those that support native languages or use translation services), the values and synonyms are imported as primary languages.
  • All entity values for both the primary and secondary languages must be unique within an entity, so you can't import a CSV if the same value has been defined more than once for a single entity. Duplicate values may occur in pre-20.12 versions, where values can be considered unique because of variations in letter casing. This is not true for 20.12, where casing is more strictly enforced. For example, you can't import a CSV if it has both PizzaSize, Small and PizzaSize, SMALL. If you plan to upgrade Version 20.12, you must first resolve all entity values that are the same, but differentiated only by letter casing before performing the upgrade.
  • Primary language support applies to skills created using Version 20.12 and higher, so you must first remove language tags and any secondary language entries before you can import a Version 20.12 CSV into a skill created with a prior version.
When you import a 20.12 CSV into a 20.12 skill:
  • You can import a multi-lingual CSV into skills that do not use native language support, including those that use translation services.
  • If you import a multi-lingual CSV into a skill that supports native languages or uses translation services, then only rows that provide a valid value for the primary language are imported. The rest are ignored.
With these caveats in mind, here's how you create entities through an import:
  1. Click Entities (This is an image of the Entities icon.) in the side navbar.

  2. Click More, choose Import Value list entities, and then select the .csv file from your local system.
    Description of import_entities.png follows
    Description of the illustration import_entities.png

  3. Add the entity or entities to an intent (or to an entity list and then to an intent).

Export Value List Entities to a CSV File
You can export the values and synonyms in a CSV file for reuse in another skill. The exported CSVs share the same format as the CSVs used for creating entities through imports in that they contain entity, value, and synonyms columns. The these CVS have release-specific requirements which can impact their reuse.
  • The CSVs exported from skills created with, or upgraded to, Version 20.12 are equipped for native language support though the primary (and sometimes secondary) language tags that are appended to the value and synonyms columns. For example, the CSV in the following snippet has a set of value and synonyms columns for the skill's primary language, English (en) and another set for its secondary language, French (fr):
    The primary language tags are included in all 20.12 CSVs regardless of native language support. They are present in skills that are not intended to perform any type of translation (native or through a translation service) and in skills that use translation services.
  • The CSVs exported from skills running on versions prior to 20.12 have the entity, value, and synonyms columns, but no language tags.
To export value list entities:
  1. Click Entities (This is an image of the Entities icon.) in the side navbar.

  2. Click More, choose Export Value list entities and then save the file.
    Description of export_entities.png follows
    Description of the illustration export_entities.png

    The exported .csv file is named for your skill. If you're going to use this file as an import, then you may need to perform some of the edits described in Import Intents from a CSV File if you're going to import it to, or export it from, Version 20.12 skills and prior versions.

Composite Bag Entities
Composite bag entities allow you to write much shorter, more compact dialog flow definitions because they can be resolved using just one component (either System.ResolveEntities or System.CommonResponse). We recommend that you use this approach, because you don't need components like System.Switch, System.setVariable, System.Text, or System.List to capture all of the user input that's required to perform some business transaction. Instead, a single component can prompt users to provide values for each item in the bag. The prompts themselves are condition-specific because they're based on the individual configuration for each bag item. Using the composite bag entity, an entity event handler (only available on Oracle Cloud Infrastructure-provisioned instances of Oracle Digital Assistant) or Apache FreeMarker, and either the System.CommonResponse and System.ResolveEntities components, your skill can:
  • Capture all free text, allow file uploads, and collect the user's current location with the STRING, ATTACHMENT, and LOCATION items.

  • Execute individual behavior for each member entity in the bag–You can add value-specific prompts and error messages for individual entities within the composite bag (which includes custom entities, system entities, and the STRING, ATTACHMENT, and LOCATION items). You can also control which entities should (or shouldn't) match the user input. Because you can create a prompt sequence, the skill can output different prompts for each user attempt.

  • Present multi-select pick lists.

  • Validate value matches based on validation rules.

  • Support for the unhappy flow–Users can correct prior entries.

  • Execute temporary, match-based transitions–The dialog flow can temporarily exit from the component when an entity has been matched, so that another state can perform a supporting function like a REST call. After the function completes, the dialog flow transitions back to the component so that the value matching can continue. For example:
    • After a user uploads a receipt, the receipt itself needs to be scanned so that values like expense date, amount, and expense type can be extracted from it for the other entities in the bag. This allows the component to fill the rest of values from the receipt, not from any user input.

    • The skill outputs a message like, “Almost there, just a few more questions” in between matching sets of entities in the bag.

    • The user input must be validated through a backend REST call. The validation might be required immediately, because it determines which of the bag items must prompt for further user input. Alternatively, the call might return information that needs to be shared with the user, like an out-of-policy warning.

    To find out how the transitionAfterMatch property that enables this functionality, see System.CommonResponse and System.ResolveEntities.

  • Disambiguate values–You can isolate a value from the user input through entity-specific prompts and component properties. These include support for corrections to prior input (the “unhappy” flow) and for prompting user input for specific built-in entity properties.

You can’t add these functions using the System.Text or System.List components. You can use these components for primitive values, but, as noted in Comparison of Dialog Flow Definitions, the System.ResolveEntities and System.CommonResponse components provide a streamlined alternative for resolving entities and non-entity values.
Explore the CbPizzaBot Skill
The CbPizzaBot skill gives you a taste of how a composite bag and System.CommonResponse component to output responses based on input values.
  • Customized Messages–Each value for the PizzaType entity is rendered as a card.

  • Global Actions–Whenever you enter an invalid value, the skill adds a value-specific error message to the card and a Cancel button, which lets you exit the dialog.

  • Multi-Value Pick List–The Toppings entity is rendered as a paginated list of values. Entering 7 (Extra Cheese) triggers a conditional message, which is a single-value list.

  • Location–The skill prompts for, and collects, the user’s coordinates (longitude and latitiude).

This skill doesn’t use any custom components for this functionality. Instead, this functionality is created declaratively.
Create a Composite Bag Entity
  1. Click Entities (This is an image of the Entities icon.) in the side navbar.

  2. Click Add Entities.

  3. Choose Composite Bag as the entity type.

  4. Enter the name and description.
  5. Click + Event Handler if you want to use execute the composite bag's prompting and logic programmatically using entity event handlers.
  6. Click + Bag Item to open the Add Bag Item dialog. If you’re adding a built-in entity or an existing custom entity, you can create a bag-specific name for it and add a description of its role within the context of the composite bag.

  7. You can fill the bag with custom entities, built-in entities and the following:
    • STRING—Captures free text from the user.

    • LOCATION—Captures the user’s location.

    • ATTACHMENT—Accepts files, audio files, video, or image files uploaded by the user. The composite bag entity stores the URL where the attachment is hosted.


    The items get resolved in the order that you add them. However, the sequence can be affected depending on how you configure individual members of the composite bag.
  8. Clicking Close returns you to the Entities page, but you can add other bag-specific capabilities to the item first (or update it later by clicking This is an image of the Edit icon. in the Entities page).

  9. Next steps:
    • Add individual error messages, disambiguation prompts, or conditional prompting for the bag items.


      These will be overwritten if you add the entity to a composite bag.
    • Add the entity to an intent. See Add Entities to Intents.

    • Configure the dialog flow to use the composite bag entity. See Configure the Dialog Flow for Composite Bag Entities and use the CbPizzaBot as a reference if you’re using the System.CommonResponse component.

Add Prompts
You can add a single prompt, or create a sequence of prompts, each providing increasingly specific information for each time the user enters an invalid value. By default, prompting is enabled. To add these prompts:
  1. If you want to enable prompting, leave the Prompt for Value field blank (its default state). Entering false in the Prompt for Value field prevents prompting. To prompt for a conditional value, add a boolean FreeMarker expression that evaluates to either true (for prompting) or false.


    When you set Prompt for Value to false, the item can still be resolved as part of another item that’s being prompted for when you enable Out of Order Extraction.
  2. Click Add Prompt to build the prompt sequence. You can reorder it by shuffling the fields through drag and drop gestures, or by renumbering them. You can randomize the output of the prompts when you give two or more prompts the same number. You can store prompts in resource bundles (for example, ${rb.askCheese}), or write them as combinations of text and FreeMarker expressions.


    You can only add prompts for built-in entities when you add them to a composite bag.
Enable Out-of-Order Extraction

You can control the slot filling and prompting by enabling and disabling Out of order Extraction. When this option is enabled for an item, its value can be slotted with no prompting. When you disable this option, the value is slotted only after it's been prompted for, even when the initial user message contains valid values.

The Out of Order Extraction option enables your skill to accept changes to previously entered values in mid-conversation and continue on. For example, the PizzaSize entity might be resolved when a customer enters I want a large pizza. However, when the composite bag prompts for the PizzaType entity, the customer might then reply Veggie please, but make it a medium. The skill can update the PizzaSize entity value with medium without restarting the conversation because the Out of Order Extraction option is enabled for the bag's PizzaSize and PizzaType items. By default, this option is enabled for all bag items.


Switch off Out of Order Extraction to prevent inadvertent matches. If you switched this option on for a STRING item, for example, the first user message would be stored by this item instead of getting matched by intended entity (which might be the first entity in the bag).

Enable Extract With
Use the Extract With option to enable your skill to resolve one bag item using the input entered for a second item in the bag. This option, which allows your skill to handle related values, provides greater flexibility for user input. Users can enter home instead of a full address, for example. Here's how:
  • The composite bag has two address-related entities: NamedAddress, a list value entity with values like home and office, and DeliveryAddress, an ADDRESS entity.
  • The DeliveryAddress entity's prompt is Where do you want that delivered?
  • The NamedAddress entity does not prompt for input (false is entered in the Prompt for Value field).
  • The NamedAddress entity can be extracted with DeliveryAddress (DeliveryAddress is selected from the Extract With menu).

When the composite bag prompts for the DeliveryAddress entity, it can resolve the entity using either a physical address, or one of the NamedAddress list values ( home or office).

Add Validation Rules
Each item in the bag can have its own validation rules. You can add a validation rule by first clicking +Validation Rule and then adding a FreeMarker expressions and a text prompt. The expression uses the following pattern to reference the item value, where varName is the name of the composite bag entity that’s declared as a context variable in the dialog flow definition:
If this expression evaluates to false, then the user input is not valid.
The following example of a validation expression is for a item called Amount. It’s a built-in entity, CURRENCY. To return a number amount for the comparison, the expression adds the CURRENCY entity’s amount property:
${expense.value.Amount.amount > 4}
The corresponding validation message can also reflect the user input through a FreeMarker expression. For example, the following message uses the type of currency extracted from the user's input as part of the validation message:
Amounts below 5 ${expense.value.Amount.currency} cannot be expensed. Enter a higher amount or type 'cancel'.
To find out about other CURRENCY properties (and the other built-in entity properties as well), see Complex Entities.
Configure the Dialog Flow for Composite Bag Entities
  1. In the context node, declare the composite bag entity as a variable:
      platformVersion: "1.1"
    main: true
    name: "ExpenseBot"
        expense: "Expense"
        iResult: "nlpresult"
  2. You can use System.ResolveEntities or System.CommonResponse. Both of these components let you leverage the composite bag entity and both provide their own benefits. The System.ResolveEntities is the simpler of the two, having a small set of properties. Unlike the System.ResolveEntities component, the System.CommonResponse provides you with more control over the UI that’s used to resolve the entities in the bag. For example, you can add conditional logic to determine prompts and value-related global actions.

  3. Reference the composite bag entity context variable in the component’s variable property (such as expense in the following examples) and then define the other properties as needed. System.ResolveEntities and The Component Properties describe them and provide further examples.

    Here’s an example of the System.ResolveEntities component:
      component: "System.ResolveEntities"
        variable: "expense"
        nlpResultVariable: "iResult"      
        cancelPolicy: "immediate"
        transitionAfterMatch: "false"
        headerText: "<#list system.updatedEntities.value>I have updated <#items as ent>${ent.description} to ${expense.value[ent.name]}<#sep> and </#items>. </#list><#list system.outOfOrderMatches.value>I got <#items as ent>the ${ent.description}<#sep> and </#items>. </#list>"
        next: "thankYou" 
    Here’s an example of the System.CommonResponse component. To activate the Show More option, you must configure the label with action defined with the system variable, system.showMore (action: "system.showMore" in the following example).
      component: "System.CommonResponse"
        processUserMessage: true
        variable: "expense"
        nlpResultVariable: "iResult"      
        cancelPolicy: "immediate"
        transitionAfterMatch: "false"
          - type: "text" 
            text: "<#list system.entityToResolve.value.updatedEntities>I have updated <#items as ent>${ent.description}<#sep> and </#items>. </#list><#list system.entityToResolve.value.outOfOrderMatches>I got <#items as ent>${ent.description}<#sep> and </#items>. </#list>"
          - type: "text" 
            text: "${system.entityToResolve.value.prompt}"
            - label: "${enumValue}"
              type: "postback"
              iteratorVariable: "system.entityToResolve.value.enumValues"
                  expense: "${enumValue}"
          - label: "Show More"
            type: "postback"
              expression: "${system.entityToResolve.value.needShowMoreButton}"
              action: "system.showMore"
                ${system.entityToResolve.value.rangeStartVar}: ${system.entityToResolve.value.nextRangeStart}
          - label: "Cancel"
            type: "postback"
              onInvalidUserInput: true
              action: "cancel"
          cancel: "ShowMenu"
          match: "afterMatch"
        next: "thankYou" 
Comparison of Dialog Flow Definitions
Because composite bag entities are modeled as a single unit, they simplify your dialog flow definition.
Task Individual Entities Composite Bag Entity
Declaring context variables. You declare context variable for several entities:
    size: "PizzaSize"
    type: "PizzaType"
    crust: "PizzaCrust"
    iResult: "nlpresult"
You declare the composite bag entity:
    pizza: "PizzaBag"
    iResult: "nlpresult"
Defining states for setting variable values. You need to define a series of states components that set values and prompt user input, such as:

When you use the nlpResultVariable property with System.List and System.Text components, you don’t need to add separate System.setVariable components.

You only need to define a single state for the System.CommonResponse component or the System.ResolveEntities component to resolve all of the entity values.
    component: "System.ResolveEntities"
      variable: "pizza"
      nlpResultVariable: "iResult"      
Referencing values for output text. Use ${variable_name.value} expressions.
    component: "System.Output"
      text: "Your ${size.value} ${type.value} pizza is on its way."
      return: "done"
Reference the context variable declared for the composite bag entity and the item within the bag: ${variable_name.value.item_name:
    component: "System.Output"
      text: "Your ${pizza.value.PizzaSize?lower_case} ${pizza.value.PizzaType?capitalize} with ${pizza.value.PizzaCrust?lower_case} crust and ${pizza.value.CheeseType?capitalize} cheese is on its way"
      return: "done"

Note: If you have set the useFullEntityMatches property to true on the System.CommonResponse component, you need to append .value or .primaryLanguageValue to the bag item name. See Custom Entity Values When useFullEntityMatches is Set to true.

The system.entityToResolve Variable
The system.entityToResolve variable tracks an entity value. You can use it to define the logic for an entity's error message, or for various properties that belong to the System.resolveEntities and System.CommonResponse components. Append the following properties to return the current entity value:
  • userInput
  • prompt
  • promptCount
  • updatedEntities
  • outOfOrderMatches
  • disambiguationValues
  • enumValues
  • needShowMoreButton
  • rangeStartVar
  • nextRangeStart
Here's an example of using this variable to return the current user input in an entity's error message:
Sorry,'${system.entityToResolve.value.userInput!'this'}' is not a valid pizza size.
Here's an example of using various system.entityToResolve definitions. Among these is a message defined for the text property, which confirms an update made to a previously set entity value using an Apache FreeMarker list directive and the updatedEntities property.
      - type: "text" 
        text: "<#list system.entityToResolve.value.updatedEntities>I have updated <#items as ent>${ent.description}<#sep> and </#items>. </#list><#list system.entityToResolve.value.outOfOrderMatches>I got <#items as ent>${ent.description}<#sep> and </#items>. </#list>"
      - type: "text" 
        text: "${system.entityToResolve.value.prompt}"
        - label: "${enumValue}"
          type: "postback"
          iteratorVariable: "system.entityToResolve.value.enumValues"
For global actions, this variable controls the Show More global action with the needShowMoreButton, rangeStartVar, and the nextRangeStart properties:
        - label: "Show More"
          type: "postback" 
            expression: "${system.entityToResolve.value.needShowMoreButton}"
            action: "system.showMore"
              ${system.entityToResolve.value.rangeStartVar}: ${system.entityToResolve.value.nextRangeStart} 
        - label: "Cancel"
          type: "postback" 
            onInvalidUserInput: true
            action: "cancel"
The Show More label must include a system.showMore (action: "system.showMore"). Otherwise, it won't function.
entityToResolve Expressions
Expression Description
${system.entityToResolve.value.resolvingField} Returns the name of the bag item.
${system.entityToResolve.value.allMatches[0].entityName} Returns the entity name that's referenced by the bag item. The allMatches array contains all of the entities whose values could potentially be updated by the user's message.
${<variable>1.value[system.entityToResolve.value.resolvingField]} Returns the bag item value that users enter or select.
${system.entityToResolve.value.userInput} Returns the text entered by the user. You can use this expression to log the user input or display it in the chat, for example, when a user enters an invalid value.
${system.entityToResolve.value.outOfOrderMatches[n].entityName} Returns the name(s) of the entities that are extracted out-of-order. Along with the values that the System.ResolveEntities or the System.CommonResponse components prompt for, users may provide additional values that trigger out-of-order value extraction and updates to other entities in the composite bag.
${system.entityToResolve.value.outOfOrderMatches[n].name} Returns the name of the composite bag item.
${system.entityToResolve.value.outOfOrderMatches? has_content?then(…,…)} Returns the value of an entity that has been matched out of order. Because it's likely that no entity has been matched out of order, this expression uses the has_content operator.
Entity Event Handlers

You can add logic and custom prompting with Apache FreeMarker expressions that you define in the Edit Composite bag page, or with entity event handlers, which can be written in JavaScript or TypeScript.

Of these two approaches, entity event handlers are more powerful, because among other things, they enable you customize messages, add custom dialogs while the entity resolves, and call REST APIs. That said, you don't have to choose entity event handlers over FreeMarker expressions. You can combine the two. For example, you can use FreeMarker expressions to specify prompts, simple validations, and simple conditional prompting using the Edit Composite bag page's Prompt for Value field and use entity event handler for more complicated functions. That said, FreeMarker syntax can be complicated, making expressions both difficult to write and debug. If you’re not familiar with FreeMarker – or if you just don’t want to use it all – then the code-oriented approach of entity event handlers might be the better option. Not only are entity event handlers easier to debug, but they also give you tighter control on how the entity resolves because JavaScript means you can use advanced logic that isn’t easily achieved (or in some cases, even possible) with FreeMarker.

Entity event handlers can simplify your dialog flow definition. First of all, they’re used with the dialog-shortening best practice that is composite bag entities. When it comes to backend services, they make your dialog even less complicated because you don’t need to write a separate state for them as you would a custom component.


The transitionAfterMatch property does not work with entity event handlers.
Event handlers simplify the dialog flow definition in another notable way: they enable you to modify the candidate skill messages generated by the System.ResolveEntities component. For example, you can create a carrousel of cards message without using the complex structure of the System.CommonResponseComponent metadata property. You can instead add the carousel through simple code, which means you can also add cards to the System.ResolveEntities component. For example, this code enables the System.ResolveEntities component to output a horizontally scrolling carousel of cards for pizza type, with card each having a cancel button:
Type: {

        publishPromptMessage: async (event, context) => {
          let candidateMessage = context.getCandidateMessages()[0];
          let pizzaInfo = getPizzaInfo();
          let MessageModel = context.getMessageModel();
          let cards = [];
          context.getEnumValues().forEach(p => {
            let orderButton = MessageModel.postbackActionObject('Order', null, {variables:{pizza:p.value}});
            cards.push(MessageModel.cardObject(p.value, pizzaInfo[p.value].description, pizzaInfo[p.value].image, null, [orderButton]));
          let message = MessageModel.cardConversationMessage('horizontal', cards, null, null, candidateMessage.text);
          MessageModel.addGlobalActions(message, candidateMessage.globalActions);
Create Entity Event Handlers

You can create an entity event handler at the entity level, or at the item level, or you can define a custom event. The bots-node-sdk’s Writing Entity Event Handlers documentation describes the overall structure of the event handler code, as well as descriptions and code samples for entity- and item-level handlers and for custom event handlers as well. The SDK also includes a reference of the EntityResolutionContext methods used by the handlers.

Entity event handlers are deployed as a custom code service. You can create the event handler using the IDE of your choice and then deploy the code using a TGZ file that you packaged manually with bots-node-sdk pack, or you can use the Event Handler Code editor that we provide. When you use our editor, you don’t have to set up your development environment or package and deploy your code. The code is deployed automatically after you save it. You can also revise the code directly without having to redeploy it, which is something you can’t do when you package and deploy a handler created with your own IDE. However, development is not limited to the Event Handler Code editor. You can use your own IDE as well, depending on your needs. The Event Handler Code editor might be a better option for small changes. If you need to make bigger changes, or add additional NPM packages, then you can download the TGZ from the Components page, unzip it, and then use your favorite editor to modify the code before repackaging and deploying it.


You can't add additional NPM packages using Event Handler Code editor. You'll need another IDE. For example, if you want to use Moment.js to work with dates, then you need to download the TGZ, add the library using the IDE of your choice, and then repackage and deploy the TGZ. After that, you can continue using the Event Handler Code editor.
You can open this editor by first clicking + Event Handler in the composite bag properties page and then by adding a service name and a handler name in the Create Service Dialog. The editor provides you with a template for the handler code that includes the entity and items objects and templates for defining events within these objects. By default, the code is populated with the entity object only. It generates the items object when you add a template for an item-level event.

By default, the entity object is populated with a ready-made publishMessage event. The components fire this event whenever the skill needs to send acknowledgement messages. It uses the updatedItemMessage and outOfOrderItemsMessage functions to acknowledge that values have been updated, or that they’ve been accepted when users enter a value other than the one prompted for. The latter is used out-of-order input situations like when a skill sends an acknowledgement message that it has accepted the user’s input for pizza crust preference when it instead prompted for pizza size.

You can leave this event as is, or you can add functionality to it. For example, you can add a Cancel button when a user’s attempts at entering a valid value have exceeded the maximum number of prompts.
publishMessage: async (event, context) => {
        //Add Cancel button for invalid values entered by users
        addCancelButtonIfNeeded(context.getCandidateMessages()[0], event, context);
function addCancelButtonIfNeeded(message, event, context) {
  if (event.promptCount > 1) {
   addGlobalAction(message, context.getMessageModel().postbackActionObject('Cancel', null, {action:'cancel'}));
Add Events
Clicking + Event enables you to and the templates for the event-level, item-level, and custom events to the code.

For example, a validate event template populates the editor with the following code for you to work with:
validate: async (event, context) => {
You can then update this template with your own code:
validate: async (event, context) => {
     if (event.newValue.value === 'PEPPERONI')
       context.addValdiationError('Type', "Sorry, no pepperoni pizzas today!");     
You can add this code to the editor, or as a shortcut, you can add it in the template menu:

You can choose from among the event types that are supported for the entity scope. Clicking Validate checks your code for design time issues, so you should click this option regularly. You can’t add further events if the code is invalid, neither can you save invalid code. Because saving code means also deploying it, you can’t deploy invalid code either.

When your code is valid, clicking Save automatically deploys it and packages it in a TGZ file. You can monitor the status of the deployment and download the TGZ file for reuse in other skills from the Components page.


To check for runtime errors, switch on Enable Component Logging and then review the logs (accessed by clicking Diagnostics > View Logs) to find about the parameters that invoked the events.
In the composite bag page, a Ready status This is an image of the Ready status icon. and an Edit icon Edit icon for revising your code becomes available after you’ve deployed the service.

Entity Event Handler Tutorials

Follow this tutorial to get acquainted with entity event handlers by creating one using the editor. Then check out this advanced tutorial for creating an entity event handler with an external IDE and bots-node-sdk.

Tutorial: Real-World Entity Extraction with Composite Bag Entities

You can get a hands-on look at creating a composite bag through this tutorial: Enable Real-World Entity Extraction with Composite Bag Entities.

Create Dynamic Entities

Dynamic entity values are managed through the endpoints of the Dynamic Entities API that are described in the REST API for Oracle Digital Assistant. To add, modify, and delete the entity values and synonyms, you must first create a dynamic entity to generate the entityId that's used in the REST calls.

To create the dynamic entity:
  1. Click + Entity.
  2. Choose Dynamic Entities from the Type list.
  3. If the backend service is unavailable or hasn't yet pushed any values, or if you do not maintain the service, click + Value to add mock values that you can use for testing purposes. Typically, you would add these static values before the dynamic entity infrastructure is in place. These values are lost when you clone, version, or export a skill. After you provision the entity values through the API, you can overwrite, or retain, these values (though in most cases you would overwrite them).
  4. Click Create.


If the API refreshes the entity values as you're testing the conversation, click Reset to restart the conversation.
A couple of notes for service developers:
  • You can query for the dynamic entities configured for a skill using the generated entityId with the botId. You include these values in the calls to create the push requests and objects that update the entity values.
  • An entity cannot have more than 150,000 values. To reduce the likelihood of exceeding this limit when you're dealing with large amounts of data, send PATCH requests with your deletions before you send PATCH requests with your additions.


Dynamic entities are only supported on instances of Oracle Digital Assistant that were provisioned on Oracle Cloud Infrastructure (sometimes referred to as the Generation 2 cloud infrastructure). If your instance is provisioned on the Oracle Cloud Platform (as are all version 19.4.1 instances), then you can't use feature.