1
votes

Using Azure Bot Framework and LUIS.ai to recognize user intent. Performing a get request to the endpoint with the text returns the json object I am expecting, however using the built-in Luis Recognizer I receive the following error: 'Cannot read property 'get' of undefined'. From the documentation here: https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-nodejs-tutorial-bf-v4 this appears to be the proper configuration so I am not sure what is going awry. Any ideas?


const { ComponentDialog, DialogSet, DialogTurnStatus, WaterfallDialog, ChoicePrompt, TextPrompt } = require('botbuilder-dialogs');
const { TopLevelDialog, TOP_LEVEL_DIALOG } = require('./topLevelDialog');

const { LuisRecognizer, QnAMaker } = require('botbuilder-ai');
const axios = require('axios');

const MAIN_DIALOG = 'MAIN_DIALOG';
const WATERFALL_DIALOG = 'WATERFALL_DIALOG';
const USER_PROFILE_PROPERTY = 'USER_PROFILE_PROPERTY';
const CHOICE_PROMPT = 'CHOICE_PROMPT';
const TEXT_PROMPT = 'TEXT_PROMPT';


class MainDialog extends ComponentDialog {
    constructor(userState) {
        super(MAIN_DIALOG);
        this.userState = userState;
        this.userProfileAccessor = userState.createProperty(USER_PROFILE_PROPERTY);

        this.addDialog(new TextPrompt(TEXT_PROMPT));
        this.addDialog(new TopLevelDialog());
        this.addDialog(new WaterfallDialog(WATERFALL_DIALOG, [
            this.initialStep.bind(this),
            this.askIfFinishedStep.bind(this),
            this.finalStep.bind(this)
        ]));

        this.initialDialogId = WATERFALL_DIALOG;

        let luisConfig = {
            applicationId: '',
            endpointKey: '',
            endpoint: '',
        };

        this.Luis = new LuisRecognizer(
            luisConfig, 
            {
                includeAllIntents: true,
                log: true,
                staging: false            
            },
            true
            );        

    }

    async run(turnContext, accessor) {
        const dialogSet = new DialogSet(accessor);
        dialogSet.add(this);

        const dialogContext = await dialogSet.createContext(turnContext);
        const results = await dialogContext.continueDialog();
        if (results.status === DialogTurnStatus.empty) {
            await dialogContext.beginDialog(this.id);
        }
    }

    async initialStep(stepContext) {

        let luisAnalysis = await this.Luis.recognize(stepContext);

        let queryString = encodeURIComponent(stepContext.context._activity.text);

        /*
         Ignore this if statement - only in use with the get request 
        */
        if(luisResponse.data.topScoringIntent.intent === 'TrainingExpiry' && luisResponse.data.topScoringIntent.score > .75)
        {
            return await stepContext.beginDialog(TOP_LEVEL_DIALOG);
        }
        else 
        {
            await stepContext.context.sendActivity("I'm sorry, that is not supported at this time or a high enough intent was not acknowledged.");
            await stepContext.context.sendActivity("Top intent: " + luisResponse.data.topScoringIntent.intent + " Score: " + luisResponse.data.topScoringIntent.score);

            return await stepContext.next();
        }        
    }

    async askIfFinishedStep(stepContext) {
        const promptOptions = { prompt: 'Is there anything else I can assist you with?' };

        return await stepContext.prompt(TEXT_PROMPT, promptOptions);
    }

    async finalStep(stepContext) {

        if(stepContext.context._activity.text.toLowerCase() === 'no')
        {
            await stepContext.context.sendActivity("Good bye");

            return await stepContext.endDialog();
        }
        else 
        {
            return await stepContext.beginDialog(MAIN_DIALOG);
        }
    }
}

module.exports.MainDialog = MainDialog;
module.exports.MAIN_DIALOG = MAIN_DIALOG;

Note: The issue was in my parameter being passed to the recognizer, as @billoverton pointed out. The solution is to pass stepContext.context.

1
Can you post more details of your error message? If should tell you where you are trying to get from an undefined property. Taking a look at that section of code would be helpful too. My initial thought is that there is some issue with your state management. The LUIS configuration itself looks fine.billoverton
@billoverton I have updated the original post with the full error message.TomBuilds
This appears to be an issue with the stepContext object you are sending to the recognizer. It doesn't contain turnState, and I suspect may not be a turnContext object. Can you log your stepContext object to console and add the results to your question?billoverton
@billoverton Thank you for following up - the issue was in my stepContext object as you pointed out. Passing stepContext.context instead of stepContext has resolved my issue. Much appreciated Bill.TomBuilds
Great! I took my comments and converted to an answer. If it looks good, please accept so that it can help others!billoverton

1 Answers

0
votes

Looking at luisRecognizer.js from the botbuilder-ai module, the error is because the recognizer is expecting a turnContext (with turnState property) and you are sending a stepContext. turnState doesn't exist on stepContext, thus the get property is failing and causing your error. If you send stepContext.context instead, that will fix the issue, i.e. let luisAnalysis = await this.Luis.recognize(stepContext.context);