constructor()

in Node/core/src/dialogs/PromptChoice.ts [76:205]


    constructor(features?: IPromptChoiceFeatures) {
        super({
            defaultRetryPrompt: 'default_choice',
            defaultRetryNamespace: consts.Library.system,
            recognizeNumbers: true,
            recognizeOrdinals: true,
            recognizeChoices: true,
            defaultListStyle: ListStyle.list,
            inlineListCount: 3,
            minScore: 0.4
        });
        this.updateFeatures(features);

        // Default recognizer logic
        this.onRecognize((context, cb) => {
            if (context.message.text && !this.features.disableRecognizer) {
                this.findChoices(context, true, (err, choices) => {
                    if (err || !choices || !choices.length) {
                        return cb(err, 0.0);
                    }

                    let topScore = 0.0;
                    let topMatch: IFindMatchResult = null;
                    let utterance = context.message.text.trim();

                    // Recognize using choices
                    if (this.features.recognizeChoices) {
                        let options = { allowPartialMatches: true };
                        let match = PromptRecognizers.findTopEntity(PromptRecognizers.recognizeChoices(utterance, choices, options));
                        if (match) {
                            topScore = match.score;
                            topMatch = match.entity
                        }
                    }

                    // Recognize index by number
                    if (this.features.recognizeNumbers) {
                        let options = { minValue: 1, maxValue: choices.length, integerOnly: true };
                        let match = PromptRecognizers.findTopEntity(PromptRecognizers.recognizeNumbers(context, options));
                        if (match && match.score > topScore) {
                            let index = Math.floor(match.entity - 1);
                            topScore = match.score;
                            topMatch = {
                                score: match.score,
                                index: index,
                                entity: choices[index].value
                            };
                        }
                    }

                    // Recognize index by ordinal
                    if (this.features.recognizeOrdinals) {
                        let match = PromptRecognizers.findTopEntity(PromptRecognizers.recognizeOrdinals(context));
                        if (match && match.score > topScore) {
                            let index = match.entity > 0 ? match.entity - 1 : choices.length + match.entity;
                            if (index >= 0 && index < choices.length) {
                                topScore = match.score;
                                topMatch = {
                                    score: match.score,
                                    index: index,
                                    entity: choices[index].value
                                };
                            } 
                        }
                    }

                    // Return result 
                    if (topScore >= this.features.minScore && topScore > 0) {
                        cb(null, topScore, topMatch);
                    } else {
                        cb(null, 0.0);
                    }
                });
            } else {
                cb(null, 0.0);
            }
        });

        // Default message formatter
        this.onFormatMessage((session, text, speak, callback) => {
            let context = (<IPromptContext>session.dialogData);
            let options = (<IPromptChoiceOptions>context.options);
            this.findChoices(session.toRecognizeContext(), false, (err, choices) => {
                let msg: IMessage;
                if (!err && choices) {
                    // Resolve list style
                    let sendChoices = context.turns === 0 || context.isReprompt;
                    let listStyle = options.listStyle;
                    if (listStyle === undefined || listStyle === null || listStyle === ListStyle.auto) {
                        // Find maximum title length
                        let maxTitleLength = 0;
                        choices.forEach((choice) => {
                            let l = choice.action && choice.action.title ? choice.action.title.length : choice.value.length;
                            if (l > maxTitleLength) {
                                maxTitleLength = l;
                            }
                        });

                        // Determine list style
                        let supportsKeyboards = Channel.supportsKeyboards(session, choices.length);
                        let supportsCardActions = Channel.supportsCardActions(session, choices.length);
                        let maxActionTitleLength = Channel.maxActionTitleLength(session);
                        let hasMessageFeed = Channel.hasMessageFeed(session);
                        if (maxTitleLength <= maxActionTitleLength && 
                            (supportsKeyboards || (!hasMessageFeed && supportsCardActions))) {
                            listStyle = ListStyle.button;
                            sendChoices = true;
                        } else {
                            listStyle = this.features.defaultListStyle;
                            let inlineListCount = this.features.inlineListCount;
                            if (listStyle === ListStyle.list && inlineListCount > 0 && choices.length <= inlineListCount) {
                                listStyle = ListStyle.inline;
                            } 
                        }
                    }

                    // Format message
                    msg = PromptChoice.formatMessage(session, listStyle, text, speak, sendChoices ? choices : null);
                }
                callback(err, msg);
            });
        });
        
        // Add repeat intent handler
        this.matches(consts.Intents.Repeat, (session) => {
            // Set to turn-0 and re-prompt.
            (<IPromptContext>session.dialogData).turns = 0;
            this.sendPrompt(session);
        });
    }