5

I've intent A and B using LUIS.ai. In intent A I'm using builder.Prompts.text to ask user couple questions. However, sometimes depending on the answer it would switched to intent B. I'm guessing it happens to match with my intent B even though I think it shouldn't. Is there a way to prevent this from happening? If I'm going through intent A's dialogs, I don't want any interruptions from other intents until I'm done. Here is an example of my code.

bot.dialog('A', [
    function (session, args, next) {
        ...
    }, 
    function (session, args, next) {
        ...
    },
    function (session, args) {
        ...
    }
]).triggerAction({
    matches: 'A'
});


bot.dialog('B', [
    function (session, args, next) {
        ...
    }, 
    function (session, args, next) {
        ...
    },
    function (session, args) {
        ...
    }
]).triggerAction({
    matches: 'B'
});
user3128376
  • 974
  • 6
  • 17
  • 40

2 Answers2

6

That's what triggerActions do to you. They can be very handy to keep your dialogs open (http://www.pveller.com/smarter-conversations-part-2-open-dialogs) but in your case they get in the way.

You can keep your dialogs immune to the global routing system, if you place them under the IntentDialog. If all you do is A and B, then this would be an un-interruptible equivalent of your code:

const intents = new builder.IntentDialog({
    recognizers: [
        new builder.LuisRecognizer(process.env.LUIS_ENDPOINT)
    ]
});

intents.matches('A', 'A');
intents.matches('B', 'B');

bot.dialog('/', intents);
bot.dialog('A', []);
bot.dialog('B', []);
Pavel Veller
  • 6,085
  • 1
  • 26
  • 24
  • 1
    Reason I switched to `triggerAction` from `IntentDialog` is to use `cancelAction` to be able to cancel the dialogs when user types "cancel/stop". Is there a way to do that if I place my intents under the `IntentDialog`? – user3128376 Apr 11 '17 at 17:25
  • 1
    You sure can, with Intent.Dialog's [cancelAction](https://docs.botframework.com/en-us/node/builder/chat-reference/classes/_botbuilder_d_.intentdialog.html#cancelaction). But in Pavel's code here he passes in a dialogId for his second parameter in `intents.matches`. This dialogId is in reference to the same dialogs you originally had sans `triggerAction`. So while the IntentDialog handles the intents, it redirects back to what you've been using so far (`UniversalBot.dialog`), allowing you to continue using `cancelAction`. – Steven G. Apr 11 '17 at 18:33
  • Not sure if I'm using it incorrectly but when I do `intent.matches('A', [...]).cancelAction(...);` anytime it matches my keyword `cancel` it goes to intent A's `cancelAction` instead of the intent I'm in (i.e. intent B). How would I make it not global? I basically have what Pavel has but I just want to add `cancelAction` to it and make it not global. Thanks – user3128376 Apr 12 '17 at 18:49
  • 2
    the `cancelAction` should attach to the *inner* dialog. You have attached it to the *outer* `IntentDialog` that is bound to `/`. You need something like `intent.matches('A', 'A')` and then `bot.dialog('A', [ ]).cancelAction()`. This would attach the cancellation action to the dialog `A` and not the `/`. Makes sense? – Pavel Veller Apr 13 '17 at 12:46
1

All you have to do is this:

var recognizer = new builder.LuisRecognizer(url) 
    .onEnabled(function (context, callback) {
        // LUIS is only ON when there are no tasks pending(e.g. Prompt text) 
        var enabled = context.dialogStack().length === 0; 
        callback(null, enabled); 
    });
rajesh-nitc
  • 5,049
  • 3
  • 25
  • 33