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); }
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)); }
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)); }
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)); }
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)))); }
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)); }
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); }
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); }
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); }
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)); }
static ParseResult MatchPhoneNumber(string text) { var match = Regex.Match(text, PhoneNumberRegex); if (match.Success) { return(ParseResult.CreateSuccess(match.Captures[0].Value)); } return(ParseResult.Failed); }
ParseResult Match(string text) { foreach (var provider in RegexProvider.ProviderNames) { if (RegexProvider.IsMatch(text, provider)) { return(ParseResult.CreateSuccess(provider)); } } return(ParseResult.Failed); }
ParseResult MatchCarrier(string text) { foreach (var carrier in Carriers.ProviderNames) { if (Carriers.IsMatch(text, carrier)) { return(ParseResult.CreateSuccess(carrier)); } } return(ParseResult.Failed); }
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)); }
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)); }
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 }))); }
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); }
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)); }
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)); }
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)); }
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)); }
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); }
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); }