question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Discussion: Bot orchestration

See original GitHub issue

Hello!

For the version 5 we are working on making a chatbot orchestration. You can see an explanation and example in this comment: https://github.com/axa-group/nlp.js/issues/713#issuecomment-724072580

You can see there the commands that are already implemented, but we want to start a dialog to get feedback about which commands can be implemented.

Also, we developed a connector for building bots using CDD (Conversation Driven Development), you can see an example here: https://github.com/axa-group/nlp.js/blob/master/packages/bot/test/bot.test.js#L54 This Unit Tests is able to run the bot and test it using an scenario described in the file scenario01.dlt, with this content:

user> hello
bot> What's your name?
user> John
bot> (Converting name to uppercases...)
bot> Hello JOHN
bot> This is the help
bot> This is the second help
bot> Bye user

So, feel free to comment what features you wish related with conversation orchestration.

Thank you!

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:2
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
jesus-seijas-spcommented, Nov 25, 2020

No, not on an onIntent because onIntent is part of the NLP, not part of the bot orchestration. But you can do it on a “call”, as explained in this same thread, is used to build actions by yourself.

But ok, step by step.

  1. In your code you can build your card dinamically, but here is an example as constant:
const card = {
  "name": "card04",
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "version": "1.0",
        "type": "AdaptiveCard",
        "speak": "Your flight is confirmed for you and 3 other passengers from San Francisco to Amsterdam on Friday, October 10 8:30 AM",
        "body": [
          {
            "type": "TextBlock",
            "text": "Passengers",
            "weight": "bolder",
            "isSubtle": false
          },
          {
            "type": "TextBlock",
            "text": "Sarah Hum",
            "separator": true
          },
          {
            "type": "TextBlock",
            "text": "Jeremy Goldberg",
            "spacing": "none"
          },
          {
            "type": "TextBlock",
            "text": "Evan Litvak",
            "spacing": "none"
          },
          {
            "type": "TextBlock",
            "text": "2 Stops",
            "weight": "bolder",
            "spacing": "medium"
          },
          {
            "type": "TextBlock",
            "text": "Fri, October 10 8:30 AM",
            "weight": "bolder",
            "spacing": "none"
          },
          {
            "type": "Input.Text",
            "placeholder": "Placeholder text",
            "id": "inputText"
          },
          {
            "type": "Input.Date",
            "id": "inputDate"
          },
          {
            "type": "Input.Time",
            "id": "inputTime"
          },
          {
            "type": "ActionSet",
            "actions": [
              {
                "type": "Action.Submit",
                "title": "Send!"
              }
            ]
          }
        ]
      }
    }
  ]
}
  1. Create the code for an action. An action receives the session, the context, and the parameters. The session contains the method “sendCard” that receives the card and the context.
const sendCard = (session, context, params) => {
  session.sendCard(card, context);
};
  1. Register the action to the bot with a name. That way you’ll be able to call this action from the script of the bot using ‘call’
  bot.registerAction('sendCard', sendCard);
  1. Define a dialog that calls this action:
dialog dialogCard
  call sendCard

Ok, now we have the dialog card, that will call the action sendCard, that sends the card. But, how to call this dialog from an intent?

  1. Create an intent where the answer is ‘/dialogCard’

  2. Run the bot, trigger the intent.

2reactions
jesus-seijas-spcommented, Nov 13, 2020

Hello, a little update of last version 4.16, and what it includes:

You have an example here: https://github.com/jesus-seijas-sp/nlpjs-examples/blob/master/04.bot

Comments If a line starts with # then is a comment. Example

# this is a comment

Import another .dlg If a line starts with import then will import other .dlgs. You can provide several separated by space:

import something.dlg ./others/other.dlg

language If a line starts with language it sets a locale for the code until another language command is found.

# this sets the language to english
language en

intents

You can add new intents using dlg. They will be added to the language of the last language command For each intent you can define the utterances, tests and answers

language en
intent agent.acquaintance
  utterances
  - say about you
  - describe yourself
  - tell me about yourself
  - who are you
  - I want to know more about you
  answers
  - I'm a virtual agent
  - Think of me as a virtual agent

entity In the same way that you can define intents, you can define entities. There are two different kind of entities that you can define: enum and regex.

entity hero
  - spiderman: spiderman, spider-man
  - ironman: ironman, iron-man
  - thor: thor
entity email 
  regex /\\b(\\w[-._\\w]*\\w@\\w[-._\\w]*\\w\\.\\w{2,3})\\b/gi

This code will create two entities: hero and email. Email is a regex entity. Hero is an enum entity with three options: spiderman, ironman and thor. Spiderman is identified when the text “spiderman” or “spider-man” is found.

dialog This will create a new dialog with a pipeline of commands. Example:

# Script for a simple turn conversation
import corpus.dlg
dialog main
  nlp
dialog hellodialog
  [!user_name] run greet
  run bye
dialog greet
  say Hello user!
  say Tell me your name
  ask user_name
  call uppers user_name
  [user_name !== 'ADMIN'] say Hello {{ user_name }}
  [user_name === 'ADMIN'] say You unblocked admin mode
dialog bye
  say Bye user 

say This is the command for the chatbot to say something to the user.

say Hello, I'm a chatbot

ask This wait for input of the user and store it into a variable. Important: this will not say anything to the user, just wait the input and store it. If you want to say something to the user, use say.

say What's your name?
ask name

This will store the input from the user in the name variable

run Executes another dialog by name. The dialog execution is an stack that stores also the last position of each dialog on the stack. Example:

dialog main
  run greet
  run help
  run bye
dialog greet
  say hello user
dialog help
  say I'm a bot
  say You can ask me questions
dialog bye
  say bye user
  • We start with stack empty: [].
  • The dialog main starts, so we put it in the stack at position 0: [main:0]
  • We read the position 0 is run greet so we move the position of main, and add the greet dialog: [main:1, greet:0]
  • We execute the “say hello user” and then greet ends, so is removed from the stack: [main: 1]
  • We are now in the line 1 of main, that is to run help, so we move main to position 2 and we add help: [main: 2, help:0]
  • We execute the “say I’m a bot” and move help to position 1: [main: 2, help: 1]
  • We execute the “say You can ask me questions” so help ends and is removed from stack: [main: 2]
  • We execute the “run bye” so we move main to next position and add bye to the stack: [main: 3, bye: 0]
  • We execute “say bye user” so bye is removed from stack: [main: 3]
  • Main does not contains more commands, so is removed from stack: []
  • As the stack is empty, it returns to the default state that is to wait for input.

nlp This command execute the input from user to the nlp and retrieve the answer. Important thing here: the answre from nlp can be a message to the user or starts by /. If the answer starts by / then it means that is to execute a dialog, so it acts as “run /dialogname”. In the example if you go to the corpus you’ll find this:

https://github.com/jesus-seijas-sp/nlpjs-examples/blob/master/04.bot/corpus.dlg#L502

intent greetings.hello
  utterances
  - hello
  - hi
  - howdy
  answers
  - /hellodialog

That means that when someone says ‘Hello’ to the bot, the dialog ‘/hellodialog’ is executed:

dialog hellodialog
  [!user_name] run greet
  run bye

inc It will increment a variable by it’s name. You can provide the increment or not, by default is 1. If the variable does not exists, then initialize it to 0 before inc.

# This will add 1 to count
inc count
# This will add 3 to count
inc count 3

dec It will decrement a variable by it’s name. You can provide the decrement or not, by default is 1. If the variable does not exists, then initialize it to 0 before dec.

# This will substract 1 from count
dec count
# This will substract 3 from count
dec count 3

set This will set a value to a variable. You can provide an expression:

# this will set count to (count*2+1)
set count count * 2 + 1

conditions You can add conditions before each command so the command will be execute if the condition is solved to truthy. Just add the condition between square brackets:

# Script for a simple turn conversation
import corpus.dlg
dialog main
  nlp
dialog hellodialog
  [!user_name] run greet
  run bye
dialog greet
  say Hello user!
  say Tell me your name
  ask user_name
  call uppers user_name
  [user_name !== 'ADMIN'] say Hello {{ user_name }}
  [user_name === 'ADMIN'] say You unblocked admin mode
dialog bye
  say Bye user

The [!user_name] run greet means that the dialog greet will be executed only if the variable user_name does not exists. When the user_name is ADMIN then the user will receive the message “You unblocked admin mode” otherwise the user will receive “Hello {{ user_name }}”

String templating When you see “Hello {{ user_name }}” that means that the part {{ user_name }} will be replaced with the variable user_name from the context.

call This is used to call functions so you can code by yourself actions for the chatbot. In the example you’ll find:

  call uppers user_name

That means that the bot will try to find the function uppers and call it with parameter “user_name”. Important: user_name will not be replaced with the user name from context, user_name will be provided exactly as is, an string with value “user_name”. The function uppers has this code:

const uppers = (session, context, params) => {
  if (params) {
    const variableName = typeof params === 'string' ? params : params[0];
    if (variableName) {
      context[variableName] = (context[variableName] || '').toUpperCase();
    }
  }
};

The way to register an action is calling bot.registerAction with the name of the action and the function to be executed:

bot.registerAction('uppers', uppers)

The signature of each action is:

  function action(session, context, params)

So the action will receive the session object, the context object and the parameters.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Make Chatbot Orchestration Easier | by Mitchell Mason
How to Make Chatbot Orchestration Easier. There's way more to building an enterprise-grade chatbot than just training data and response content.
Read more >
Bots are easy enough, orchestration is not. - LinkedIn
Here is why we believe creating a single purpose 'chatbot' isn't too hard, orchestration is the challenging part.
Read more >
Chatbot Orchestration at Scale - ProcessMaker
Thus, a chatbot thrives at reducing response times, quickly resolving issues, and boosting brand exposure when it comes to consumer-facing ...
Read more >
RaphaelChevallier/Multi-Chatbot-Orchestration-Framework
Multi-Chatbot-Orchestration-Framework. A framework where multiple chatbots of differing specialties can work together to answer any intent accurately to a user ...
Read more >
Seamless Multi-bot Orchestration in the Enterprise | L3-AI 2021
Last year at L3-AI, Akela Drissner gave a talk entitled “Meta bots : why they're probably not the solution to your problems”.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found