function evaluate()

in Cognitive Services/Node/src/LuisActionBinding.js [68:212]


function evaluate(modelUrl, actions, currentActionModel, userInput, onContextCreationHandler) {
    if (!modelUrl) {
        throw new Error('modelUrl not set');
    }

    actions.forEach(validateAction);

    onContextCreationHandler = validateContextCreationHandler(onContextCreationHandler);

    return new Promise(function (resolve, reject) {
        var actionModel = _.merge({}, EmptyActionModel, currentActionModel);

        if (actionModel.status === Status.ContextSwitch) {
            // confirming switch context
            if (actionModel.confirmSwitch) {
                // re-write current model
                actionModel.intentName = actionModel.contextSwitchData.intentName;
                actionModel.parameters = actionModel.contextSwitchData.parameters;
            }

            // force continue with validation
            actionModel.contextSwitchData = null;
            actionModel.currentParameter = null;
            actionModel.userInput = null;
        }

        // normalize input
        actionModel.userInput = userInput ? userInput.trim() : null;

        // cleanup from previous runs
        delete actionModel.subcontextResult;

        switch (actionModel.status) {
            case Status.NoActionRecognized:
                // First time input, resolve to action
                builder.LuisRecognizer.recognize(actionModel.userInput, modelUrl, (err, intents, entities) => {
                    if (err) {
                        return reject(err);
                    }

                    var action = chooseBestIntentAction(intents, actions);
                    if (action) {
                        // Populate action parameters with LUIS entities
                        actionModel.intentName = action.intentName;
                        // Contextual action? Populate with root action
                        if (action.parentAction && !actionModel.contextModel) {
                            popupateContextParent(actionModel, action, actions);
                        }

                        // extract parameters from entities
                        actionModel.parameters = extractParametersFromEntities(action.schema, entities);

                        var next = function () {
                            // Run validation
                            tryExecute(action, actionModel)
                                .then(resolve)
                                .catch(reject);
                        };

                        if (action.parentAction) {
                            // Invoke custom onContextCreationHandler, may inject more parameters to contextModel (the parent's actionModel)
                            // Wait for onContextCreation handler's callback to continue execution
                            onContextCreationHandler(action.parentAction, actionModel.contextModel, next);
                        } else {
                            next();
                        }

                    } else {
                        // No action recognized
                        actionModel.status = Status.NoActionRecognized;
                        resolve(actionModel);
                    }
                });
                break;

            case Status.MissingParameters:
            case Status.ContextSwitch:
                var action = _.find(actions, function (action) { return actionModel.intentName === action.intentName; });

                if (actionModel.userInput) {
                    // Filling for a missing parameter
                    builder.LuisRecognizer.recognize(actionModel.userInput, modelUrl, (err, intents, entities) => {
                        if (err) {
                            return reject(err);
                        }

                        var newAction = chooseBestIntentAction(intents, actions, action);
                        if (newAction && newAction.intentName !== action.intentName) {
                            if (newAction.parentAction === action) {
                                // context action (sub action), replace action & model and continue
                                actionModel = _.merge({}, EmptyActionModel, {
                                    contextModel: actionModel,
                                    intentName: newAction.intentName
                                });
                                actionModel.parameters = [];
                                action = newAction;

                            } else if (equalsTrue(action.confirmOnContextSwitch, true)) {

                                // new context switch
                                actionModel.status = Status.ContextSwitch;
                                actionModel.contextSwitchData = {
                                    intentName: newAction.intentName,
                                    parameters: extractParametersFromEntities(newAction.schema, entities)
                                };

                                // prompt
                                var currentActionName = action.friendlyName || action.intentName;
                                var newActionName = newAction.friendlyName || newAction.intentName;
                                actionModel.contextSwitchPrompt = util.format('Do you want to discard the current action \'%s\' and start the with \'%s\' action?', currentActionName, newActionName);

                                // return and wait for context switch confirmation
                                return resolve(actionModel);

                            } else {
                                // switch to new context and continue with evaluation
                                action = newAction;
                                actionModel.intentName = newAction.intentName;
                                actionModel.currentParameter = null;
                            }
                        }

                        var parameters = extractParametersFromEntities(action.schema, entities, actionModel);

                        // merge new identified parameters from entites
                        actionModel.parameters = _.merge({}, actionModel.parameters, parameters);

                        // Run validation
                        tryExecute(action, actionModel)
                            .then(resolve)
                            .catch(reject);
                    });
                } else {
                    // Run validation with current model
                    tryExecute(action, actionModel)
                        .then(resolve)
                        .catch(reject);
                }
                break;

            default:
                reject('Unknown action.status "' + actionModel.status + '"');
        }
    });
}