Extending Microsoft’s Bot Framework with Graph-Based Dialogs



Image: DNA by Arthur Caranta, used by CC BY 2.0


Pager uses technology to help patients better navigate an expansive healthcare landscape and connect them to quality care. The company is exploring using bot technology to automate larger portions of their platform, and we collaborated with them on this project.

Many patients are not aware that the assessment of the nature and severity of their condition begins the moment they to arrange an appointment or walk into a hospital. Whether through a phone call, in person, or online, health systems solicit a patient’s chief complaint in order to understand the urgency of a situation. Patients first identify themselves, and then a representative asks a series of questions in order to understand whether the patient is the right fit for that specific venue of care. For acute conditions, the process follows a triage protocol based on the patient’s description of symptoms. For example, a patient with a headache would be asked details about the type of pain, speed of onset, associated symptoms such as numbness, weakness, or fever.

For experienced nurses and other clinicians, the protocols are second nature and committed to memory and are used to identify potentially unstable conditions that require more immediate attention. Past medical history, risk factors, and other demographic information is used to risk stratify patients. In addition, insurance and other financial data is obtained to determine whether the care will be covered, and together with the medical data, to direct the patient to the most suitable care environment.

For Pager, using human representatives (nurses in this case) to conduct scripted protocols through a text interface is time-consuming, hard to scale, and error prone.

The Problem

Before this engagement, if a developer wanted to build a dialog for a protocol using the Microsoft Bot Framework, they had to hard-code each of the individual dialog steps in the bot service. Since Pager has hundreds of different protocols, they wanted to be able to dynamically load the dialogs from an external data source, such as a file, or a database. Dynamic loading of protocols also allows Pager to update their bot without needing to change and redeploy its code.

Additionally, Bot Framework uses a relatively basic waterfall conversation paradigm for modeling conversations:

  • The developer provides a hard-coded list of steps, where each step is an interaction with the user, and waits for a response.
  • The framework sends the question to the user. When the user replies, the framework gets the input and transfers it to the next step in the waterfall.

The problem is that most types of conversation do not look like a waterfall, but more like a graph. Each interaction with the user is represented as a node, and, according to the user’s input, the conversation should be able to flow to different nodes in that graph. This flow can be implemented using only Bot Framework’s APIs, but it is not a straightforward or easily reusable process to implement.

The Engagement

We collaborated with Pager to develop an extension for Bot Framework that supports graph-based dialogs and dynamic loading of those dialogs from an external data source. The dialogs are then stored using a JSON schema. The extension is a Node.js module that was implemented using TypeScript.

The following are some of the features that are supported by this extension:

  • Embedding dialogs: Common dialogs (scenarios) can be separated and embedded as a single step in other dialogs.
  • Scoring against multiple LUIS APIs: Calling multiple LUIS models and deciding what to do next based on the scoring. This action can be done in any step of the conversation, not only in the first step as it is demonstrated today using Bot Framework.
  • Custom code handlers: Providing external handlers (either embedded in the JSON or by providing a handler loader callback to the library).
  • Extendable schema: Providing custom step handlers to be able to extend the dialog with custom node types beyond the ones that are natively supported by the extension.

An example of using the library:

// handler for loading scenarios from external datasource
function loadScenario(scenario) {
    return new Promise((resolve, reject) => {
        console.log('loading scenario', scenario);

        // implement loadScenario from external datasource.
        var scenarioObj = ...

        scenario: 'smoking'
    .then(graphDialog => bot.dialog('/smoking', graphDialog.getDialog()));

An example of a smoking scenario:

  "id": "smoking",
  "type": "sequence",
  "steps": [
      "id": "isSmoking",
      "type": "prompt",
      "data": { "type": "confirm", "text": "Do you smoke?" },
      "scenarios": [
          "condition": "isSmoking",
          "steps": [
              "id": "smokeTime",
              "type": "prompt",
              "data": { "type": "number", "text": "For how many years?" }
          "condition": "!isSmoking",
          "steps": [
              "id": "sureNotSmoking",
              "type": "prompt",
              "data": { "type":"confirm", "text": "Are you sure?" },
              "scenarios": [
                  "condition": "!sureNotSmoking",
                  "nodeId": "isSmoking"
  • Using "condition": "!sureNotSmoking" relates to the sureNotSmoking node’s boolean value (the input for "Are you sure?")
  • Using "nodeId": "isSmoking" means that the dialog will jump to step isSmoking to collect that answer again.

For more details about the schema, please see the repositories below.

The Code

Two repositories are available that include instructions on how to run and use the code in addition to code samples:

  • bot-graph-dialog: The actual TypeScript implementation of the Node.js extension
  • bot-trees: A sample bot service that demonstrates how to use the bot-graph-dialog extension

Opportunities for Reuse

The bot-graph-dialog extension can be plugged in to enhance or completely recreate any new or existing Node.js bot running on top of Bot Framework. It can be used to dynamically load dialogs from external data sources and embed these dialogs in any of the existing APIs that get a waterfall array of steps. Also, since the extension itself is extendable, it can be extended with custom types of nodes, with external handlers and much more.


Comments are closed. Login to edit/delete your existing comments