Ejemplo n.º 1
0
        public override async Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            string agentName = state.GlobalAnswers.GetFieldAnswer <string>(ChatStandardField.AgentName);

            (var names, var tokens) = await GetNamesAndTokens(message.UserInput, agentName);

            if (tokens == null)
            {
                logger.Error("Network: Failed to call text parser service.");
                return(ParseResult.Failed);
            }

            // If we didnt detect any names, and the user entered only 2 or 3 words (possible names),
            // and no look behind (to cut down on false positives), we retry with "My name is " prepended
            // since the NLP is better at picking up names in a sentence.
            if ((names.Count == 0) && (tokens.Count <= 3) && (!chatParseField.CheckPreviousMessages))
            {
                (names, tokens) = await GetNamesAndTokens("My name is " + message.UserInput, agentName);
            }

            names.AddRange(GetUndetectedNames(message.UserInput));

            // Add our test name if detected
            if (message.UserInput.ToUpper().Contains(TestName.ToUpper()))
            {
                names.AddRange(TestName.Split(' '));
            }

            if (names.Count > 0)
            {
                return(ParseResult.CreateSuccess(names.Distinct().ToArray()));
            }

            return(ParseResult.Failed);
        }
Ejemplo n.º 2
0
        public override Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            var tokens = TextClassificationService.Tokenize(message.UserInput);

            // HTC One and iPhone match words quite easily
            var cleanedTokens = (from t in tokens
                                 where t != "phone" && t != "phones" && t != "phone's" && t != "the" && t != "tone"
                                 select t.ToLower()).ToArray();

            (string matchedText, int matchedIndex, float ratio) = MatchService.FindMatch(cleanedTokens, 1, 4, deviceCatalog.MatchCharacters);
            var device = deviceCatalog.MakeModelList[matchedIndex];

            var deviceMatch = new DeviceMatchResult
            {
                Id          = device.Id,
                Make        = device.Make,
                Model       = device.Model,
                DisplayName = device.DisplayName,
                IsUncommon  = device.IsUncommon,
                Ratio       = ratio
            };

            double minConfidence = ChatConfiguration.MinimumDeviceConfidence;

            if (device.IsUncommon)
            {
                minConfidence = ChatConfiguration.MinimumUncommonDeviceConfidence;
            }
            if (deviceMatch.Ratio > minConfidence)
            {
                return(Task.FromResult(ParseResult.CreateSuccess(deviceMatch)));
            }

            return(Task.FromResult(ParseResult.Failed));
        }
Ejemplo n.º 3
0
        public override async Task <ParseResult> ParseAsync(ChatState chatState, Chat_ParseField chatParseField, ChatMessage message)
        {
            int timezoneOffset = chatState.GetUserTimeZoneOffset();

            if (message.LuisDateOutput == null)
            {
                message.LuisDateOutput = await luisService.Parse(message.UserInput, timezoneOffset);
            }

            var assumeFuture = false;

            if (bool.TryParse(chatParseField?.GetProperty("AssumeFuture"), out bool test))
            {
                assumeFuture = test;
            }

            var results = ExtractDateResults(chatState, message.LuisDateOutput, assumeFuture);

            if ((results == null) || (results.Length == 0))
            {
                logger.InfoFormat("Parse: luis date parser got nothing. - {0}", (message.LuisDateOutput != null) ? JsonConvert.SerializeObject(message.LuisDateOutput) : "null");
                return(ParseResult.Failed);
            }

            if (version == 1)
            {
                return(ProcessAsV1Date(message, timezoneOffset, results));
            }

            return(ParseResult.CreateSuccess(results));
        }
Ejemplo n.º 4
0
        public override Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            string text = GetTextSource(chatParseField, message);

            // Shortcut for common case where flow tries to take all user input.
            // .* regex means all characters EXCEPT newlines. But the flow wants all including newlines
            // so running regex to collect all data doesn't make sense. So we just set the variable to everything.
            if (chatParseField.RuleData == ".*")
            {
                return(Task.FromResult(ParseResult.CreateSuccess(text)));
            }

            string regex = chatParseField?.GetProperty("Regex") ?? chatParseField.RuleData;

            try
            {
                var match = Regex.Match(text, regex, RegexOptions.IgnoreCase, ChatConfiguration.RegexTimeout);
                if (match.Success)
                {
                    if (String.IsNullOrEmpty(chatParseField.Answer))
                    {
                        return(Task.FromResult(ParseResult.CreateSuccess(match.Value)));
                    }

                    return(Task.FromResult(ParseResult.CreateSuccess(chatParseField.Answer)));
                }
            }
            catch (RegexMatchTimeoutException)
            {
                logger.ErrorFormat("Regex timed out. {0}", regex);
            }

            return(Task.FromResult(ParseResult.Failed));
        }
Ejemplo n.º 5
0
        public override Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            var matches = Regex.Matches(message.UserInput, @"\d+")
                          .Cast <Match>()
                          .Select(m => m.Value)
                          .ToArray();

            if (matches.Length == 0)
            {
                return(Task.FromResult(ParseResult.Failed));
            }

            var setting = chatParseField?.GetProperty("AllowedValues");

            if (String.IsNullOrEmpty(setting))
            {
                return(Task.FromResult(ParseResult.CreateSuccess(int.Parse(matches[0]))));
            }

            var allowedValues = setting.Split(',', ' ');

            var foundValue = allowedValues.Where(b => matches.Any(a => b.Contains(a))).FirstOrDefault();

            if (foundValue == null)
            {
                return(Task.FromResult(ParseResult.Failed));
            }

            return(Task.FromResult(ParseResult.CreateSuccess(int.Parse(foundValue))));
        }
Ejemplo n.º 6
0
        public override async Task <ParseResult> ParseAsync(ChatState chatState, Chat_ParseField chatParseField, ChatMessage message)
        {
            var preFlowName  = chatParseField.GetProperty("preFlowName");
            var preStepId    = chatParseField.GetProperty("preStepId");
            var postFlowName = chatParseField.GetProperty("postFlowName");
            var postStepId   = chatParseField.GetProperty("postStepId");

            if (String.IsNullOrEmpty(preFlowName) ||
                String.IsNullOrEmpty(preStepId) ||
                String.IsNullOrEmpty(postFlowName) ||
                String.IsNullOrEmpty(postStepId))
            {
                throw new ApplicationException("Parse: Missing rule data for IntentGateway Parser.");
            }

            message.Classifications = await ClassifyText(message.CorrectedUserInput, preFlowName, preStepId, postFlowName, postStepId, chatState.SessionData.IsSmsChannel);

            chatState.UpdateLastClassification(message.Classifications);

            if (!message.Classifications.IsSuccessful)
            {
                return(ParseResult.Failed);
            }

            // We don't want common chat intent's here.
            var intent = chatState.LastClassification.GetBestResult().Intent;

            if (intent != null && intent.StartsWith("commonchat-"))
            {
                return(ParseResult.Failed);
            }

            return(ParseResult.CreateSuccess(message.Classifications.GetBestResult().Result));
        }
Ejemplo n.º 7
0
        static ParseResult MatchBadPhoneNumber(string text)
        {
            string strip = StripToNumber(text);

            if ((strip.Length >= ChatConfiguration.MinimumBadPhoneDigitCount) && (strip.Length <= ChatConfiguration.MaximumBadPhoneDigitCount))
            {
                return(ParseResult.CreateSuccess(strip));
            }

            return(ParseResult.Failed);
        }
Ejemplo n.º 8
0
        ParseResult MatchEmail(string regex, string text)
        {
            var match = Regex.Match(text, regex, RegexOptions.IgnoreCase);

            if (match.Success)
            {
                return(ParseResult.CreateSuccess(match.Captures[0].Value));
            }

            return(ParseResult.Failed);
        }
Ejemplo n.º 9
0
        public override async Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            var output = await addressParseService.Parse(chatId, state, GetTextSource(chatParseField, message));

            if (output?.addresses?.Length > 0)
            {
                return(ParseResult.CreateSuccess(output.addresses));
            }

            return(ParseResult.Failed);
        }
Ejemplo n.º 10
0
        public override Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            var match = Regex.Match(GetTextSource(chatParseField, message), ZipCodeRegex);

            if (match.Success)
            {
                return(Task.FromResult(ParseResult.CreateSuccess(match.Captures[0].Value)));
            }

            return(Task.FromResult(ParseResult.Failed));
        }
Ejemplo n.º 11
0
        static ParseResult MatchPhoneNumber(string text)
        {
            var match = Regex.Match(text, PhoneNumberRegex);

            if (match.Success)
            {
                return(ParseResult.CreateSuccess(match.Captures[0].Value));
            }

            return(ParseResult.Failed);
        }
Ejemplo n.º 12
0
        ParseResult Match(string text)
        {
            foreach (var provider in RegexProvider.ProviderNames)
            {
                if (RegexProvider.IsMatch(text, provider))
                {
                    return(ParseResult.CreateSuccess(provider));
                }
            }

            return(ParseResult.Failed);
        }
Ejemplo n.º 13
0
        ParseResult MatchCarrier(string text)
        {
            foreach (var carrier in Carriers.ProviderNames)
            {
                if (Carriers.IsMatch(text, carrier))
                {
                    return(ParseResult.CreateSuccess(carrier));
                }
            }

            return(ParseResult.Failed);
        }
Ejemplo n.º 14
0
        private ParseResult ProcessAsV1Date(ChatMessage message, int timezoneOffset, DateTimeParseResult[] results)
        {
            var v1LuisDate = ExtractV1DateResults(results, timezoneOffset);

            if (v1LuisDate == null)
            {
                logger.InfoFormat("Parse: luis date parser got nothing. - {0}", (message.LuisDateOutput != null) ? JsonConvert.SerializeObject(message.LuisDateOutput) : "null");
                return(ParseResult.Failed);
            }

            return(ParseResult.CreateSuccess(v1LuisDate.Value));
        }
Ejemplo n.º 15
0
        public override Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            foreach (var provider in BackupProviders.ProviderNames)
            {
                if (BackupProviders.IsMatch(message.CorrectedUserInput, provider))
                {
                    return(Task.FromResult(ParseResult.CreateSuccess(provider)));
                }
            }

            return(Task.FromResult(ParseResult.Failed));
        }
Ejemplo n.º 16
0
        public override Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            var(text, index, ratio) = MatchService.FindMatch(message.UserInput.ToLower(), 1, MaxTokenMatch, colorCatalog.ColorCodeChars);

            if (ratio < ChatConfiguration.MinimumColorMatchRatio)
            {
                return(Task.FromResult(ParseResult.Failed));
            }

            var color = colorCatalog.Colors[index];

            return(Task.FromResult(ParseResult.CreateSuccess(new ColorResult {
                Name = color.name, Ratio = ratio
            })));
        }
Ejemplo n.º 17
0
        public override async Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            if (message.LuisDamageClassifierOutput == null)
            {
                message.LuisDamageClassifierOutput = await luisService.Parse(message.CorrectedUserInput, 0);
            }

            string[] intents = message.LuisDamageClassifierOutput.GetIntents(ChatConfiguration.MinLuisConfidenceRatio);

            if (intents?.Length > 0)
            {
                return(ParseResult.CreateSuccess(intents));
            }

            // AVA-997: Always use None if we didn't parse anything.
            return(ParseResultNoneList);
        }
Ejemplo n.º 18
0
        public override Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            if (String.Compare(message.CorrectedUserInput, "view solution", true) == 0)
            {
                return(Task.FromResult(ParseResult.CreateSuccess("viewedSolution")));
            }
            else if (Regex.IsMatch(message.CorrectedUserInput, ContinueRegex, RegexOptions.IgnoreCase))
            {
                return(Task.FromResult(ParseResultYes));
            }
            else if (Regex.IsMatch(message.CorrectedUserInput, YesNoParser.NoRegex, RegexOptions.IgnoreCase))
            {
                return(Task.FromResult(ParseResultNo));
            }

            return(Task.FromResult(ParseResult.Failed));
        }
Ejemplo n.º 19
0
        public override Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            var matches = Regex.Matches(GetTextSource(chatParseField, message), AppNamesRegex, RegexOptions.IgnoreCase);

            if (matches.Count > 0)
            {
                string[] apps = new string[matches.Count];

                for (int i = 0; i < matches.Count; i++)
                {
                    apps[i] = matches[i].Value;
                }

                return(Task.FromResult(ParseResult.CreateSuccess(apps)));
            }

            return(Task.FromResult(ParseResult.Failed));
        }
Ejemplo n.º 20
0
        public override Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            var matches = Regex.Matches(message.CorrectedUserInput, BluetoothDeviceNoRegex, RegexOptions.IgnoreCase);

            if (matches.Count > 0)
            {
                string[] apps = new string[matches.Count];

                for (int i = 0; i < matches.Count; i++)
                {
                    apps[i] = matches[i].Value;
                }

                return(Task.FromResult(ParseResult.CreateSuccess(apps)));
            }

            return(Task.FromResult(ParseResult.Failed));
        }
Ejemplo n.º 21
0
        public override async Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            int matchThreshold = ChatConfiguration.FuzzyNameMatchThreshold;

            if (!String.IsNullOrEmpty(chatParseField.RuleData))
            {
                matchThreshold = Convert.ToInt32(chatParseField.RuleData);
            }

            FuzzyMatchParserData[] possibleMatches = await GetPossibleMatches(state, chatFlowStep, chatParseField);

            if (UtilityMethods.IsNullOrEmpty(possibleMatches))
            {
                logger.WarnFormat("Parse: Invalid field data for fuzzy match. {0} - {1}", chatParseField.FieldName, chatParseField.SourceData);
                return(ParseResult.Failed);
            }

            // Get list of test values for API
            var testVals = possibleMatches.Select(x => x.text).ToArray();
            var response = await fuzzyMatchService.Match(GetTextSource(chatParseField, message), testVals);

            if (response == null)
            {
                logger.Error("Network: Failed to call fuzzy match service.");
                return(ParseResult.Failed);
            }

            if (response.Output?.Length > 0)
            {
                IEnumerable <FuzzyMatchParserResult> matches = FindMatches(matchThreshold, possibleMatches, response);

                if (matches.Count() > 0)
                {
                    return(ParseResult.CreateSuccess(matches.First()));
                }
            }
            else
            {
                logger.Debug("Parse: No fuzzy matches found.");
            }

            // Always return true that we processed the text even if we didnt find a matching name.
            return(ParseResult.CreateSuccess(null));
        }
Ejemplo n.º 22
0
        public override async Task <ParseResult> ParseAsync(ChatState state, Chat_ParseField chatParseField, ChatMessage message)
        {
            if (message.LuisDateOutput == null)
            {
                message.LuisDateOutput = await luisService.Parse(message.UserInput, state.GetUserTimeZoneOffset());
            }

            if (message.LuisDateOutput?.Entities.Length > 0)
            {
                var v1Entities = ExtractV1TimeEntities(state, message.LuisDateOutput);
                if (v1Entities.Length > 0)
                {
                    return(ParseResult.CreateSuccess(v1Entities));
                }
            }

            logger.DebugFormat("Parse: Luis Time Parser got nothing. - {0}", (message.LuisDateOutput != null) ? JsonConvert.SerializeObject(message.LuisDateOutput) : "null");

            return(ParseResult.Failed);
        }
Ejemplo n.º 23
0
        public override async Task <ParseResult> ParseAsync(ChatState chatState, Chat_ParseField chatParseField, ChatMessage message)
        {
            // Strip PII data
            string text        = filterService.FilterUserData(chatState, message.CorrectedUserInput, false);
            string classifiers = chatParseField?.GetProperty("Classifiers") ?? defaultClassifier;

            message.Classifications = await classificationService.ClassifyAsync(classifiers, threshold, text, false, chatState.SessionData.IsSmsChannel);

            chatState.UpdateLastClassification(message.Classifications);

            if (message.Classifications.IsSuccessful)
            {
                // We don't want common chat intent's here.
                if (message.Classifications.GetBestResult().Intent.StartsWith("commonchat-"))
                {
                    return(ParseResult.Failed);
                }

                return(ParseResult.CreateSuccess(message.Classifications.GetBestResult().Intent));
            }

            return(ParseResult.Failed);
        }