private async Task <RecognizerResult> RecognizeAsync(ITurnContext turnContext, string utterance, LuisV3.LuisPredictionOptions options, HttpClient httpClient, CancellationToken cancellationToken) { RecognizerResult recognizerResult; JObject luisResponse = null; if (string.IsNullOrWhiteSpace(utterance)) { recognizerResult = new RecognizerResult { Text = utterance }; } else { luisResponse = await GetLuisResponseAsync(utterance, options, httpClient, cancellationToken).ConfigureAwait(false); recognizerResult = BuildRecognizerResultFromLuisResponse(luisResponse, utterance); } var traceInfo = JObject.FromObject( new { recognizerResult, luisModel = new { ModelID = Application.ApplicationId, }, luisOptions = options, luisResult = luisResponse, }); await turnContext.TraceActivityAsync("LuisRecognizer", traceInfo, LuisTraceType, LuisTraceLabel, cancellationToken).ConfigureAwait(false); return(recognizerResult); }
private async Task <RecognizerResult> RecognizeInternalAsync(ITurnContext turnContext, Dictionary <string, string> telemetryProperties, Dictionary <string, double> telemetryMetrics, CancellationToken cancellationToken) { BotAssert.ContextNotNull(turnContext); if (turnContext.Activity.Type != ActivityTypes.Message) { return(null); } var utterance = turnContext.Activity?.AsMessageActivity()?.Text; if (string.IsNullOrWhiteSpace(utterance)) { throw new ArgumentNullException(nameof(utterance)); } var luisResult = await _runtime.Prediction.ResolveAsync( _application.ApplicationId, utterance, timezoneOffset : _options.TimezoneOffset, verbose : _options.IncludeAllIntents, staging : _options.Staging, spellCheck : _options.SpellCheck, bingSpellCheckSubscriptionKey : _options.BingSpellCheckSubscriptionKey, log : _options.Log ?? true, cancellationToken : cancellationToken).ConfigureAwait(false); var recognizerResult = new RecognizerResult { Text = utterance, AlteredText = luisResult.AlteredQuery, Intents = LuisUtil.GetIntents(luisResult), Entities = LuisUtil.ExtractEntitiesAndMetadata(luisResult.Entities, luisResult.CompositeEntities, _options.IncludeInstanceData ?? true), }; LuisUtil.AddProperties(luisResult, recognizerResult); if (_includeApiResults) { recognizerResult.Properties.Add("luisResult", luisResult); } // Log telemetry await OnRecognizerResultAsync(recognizerResult, turnContext, telemetryProperties, telemetryMetrics, cancellationToken).ConfigureAwait(false); var traceInfo = JObject.FromObject( new { recognizerResult, luisModel = new { ModelID = _application.ApplicationId, }, luisOptions = _options, luisResult, }); await turnContext.TraceActivityAsync("LuisRecognizer", traceInfo, LuisTraceType, LuisTraceLabel, cancellationToken).ConfigureAwait(false); return(recognizerResult); }
private async Task SendErrorMessageAsync(ITurnContext turnContext, Exception exception) { try { // Send a message to the user. var errorMessageText = "The bot encountered an error or bug."; var errorMessage = MessageFactory.Text(errorMessageText, errorMessageText, InputHints.IgnoringInput); errorMessage.Value = exception; await turnContext.SendActivityAsync(errorMessage); await turnContext.SendActivityAsync($"Exception: {exception.Message}"); await turnContext.SendActivityAsync(exception.ToString()); errorMessageText = "To continue to run this bot, please fix the bot source code."; errorMessage = MessageFactory.Text(errorMessageText, errorMessageText, InputHints.ExpectingInput); await turnContext.SendActivityAsync(errorMessage); // Send a trace activity, which will be displayed in the Bot Framework Emulator. await turnContext.TraceActivityAsync("OnTurnError Trace", exception.ToString(), "https://www.botframework.com/schemas/error", "TurnError"); } catch (Exception ex) { _logger.LogError(ex, $"Exception caught in SendErrorMessageAsync : {ex}"); } }
public async Task OnExceptionAsync(ITurnContext turnContext, Exception exception) { await turnContext.SendActivityAsync("Sorry, it looks like something went wrong."); if (environment.IsDevelopment()) { await turnContext.TraceActivityAsync("Exception", exception); } }
public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default) { if (reason == DialogReason.CancelCalled || reason == DialogReason.ReplaceCalled) { await turnContext.TraceActivityAsync($"{GetType().Name}.EndDialogAsync()", label : $"ActivityType: {turnContext.Activity.Type}", cancellationToken : cancellationToken).ConfigureAwait(false); var activity = (Activity)Activity.CreateEndOfConversationActivity(); ApplyParentActivityProperties(turnContext, activity, null); await SendToSkillAsync(null, (Activity)activity, cancellationToken).ConfigureAwait(false); } await base.EndDialogAsync(turnContext, instance, reason, cancellationToken).ConfigureAwait(false); }
private async Task ProcessTurnError(ITurnContext turnContext, Exception ex) { if (logger != null) { logger.LogError(ex, $"[OnTurnError] Error : {ex.Message}"); } await turnContext.SendActivityAsync("The bot encountered an error"); await turnContext.TraceActivityAsync("OnTurnError Trace", ex.Message, "https://www.botframework.com/schemas/error", "TurnError"); if (conversationState != null) { await conversationState.DeleteAsync(turnContext); } }
private async Task SendErrorMessageAsync(ITurnContext turnContext, Exception exception) { try { _telemetryClient.TrackException(exception); // Send a message to the user. await turnContext.SendActivityAsync(_templateEngine.GenerateActivityForLocale(RestaurantBookingSharedResponses.ErrorMessage)); // Send a trace activity, which will be displayed in the Bot Framework Emulator. // Note: we return the entire exception in the value property to help the developer; // this should not be done in production. await turnContext.TraceActivityAsync("OnTurnError Trace", exception.ToString(), "https://www.botframework.com/schemas/error", "TurnError"); } catch (Exception ex) { _logger.LogError(ex, $"Exception caught in SendErrorMessageAsync : {ex}"); } }
public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default) { // Send of of conversation to the skill if the dialog has been cancelled. if (reason == DialogReason.CancelCalled || reason == DialogReason.ReplaceCalled) { await turnContext.TraceActivityAsync($"{GetType().Name}.EndDialogAsync()", label : $"ActivityType: {turnContext.Activity.Type}", cancellationToken : cancellationToken).ConfigureAwait(false); var activity = (Activity)Activity.CreateEndOfConversationActivity(); // Apply conversation reference and common properties from incoming activity before sending. activity.ApplyConversationReference(turnContext.Activity.GetConversationReference(), true); activity.ChannelData = turnContext.Activity.ChannelData; activity.Properties = turnContext.Activity.Properties; await SendToSkillAsync(turnContext, activity, cancellationToken).ConfigureAwait(false); } await base.EndDialogAsync(turnContext, instance, reason, cancellationToken).ConfigureAwait(false); }
internal override async Task <RecognizerResult> RecognizeInternalAsync(ITurnContext turnContext, HttpClient httpClient, CancellationToken cancellationToken) { BotAssert.ContextNotNull(turnContext); if (turnContext.Activity == null || turnContext.Activity.Type != ActivityTypes.Message) { return(null); } var utterance = turnContext.Activity.AsMessageActivity()?.Text; RecognizerResult recognizerResult; LuisResult luisResult = null; if (string.IsNullOrWhiteSpace(utterance)) { recognizerResult = new RecognizerResult { Text = utterance }; } else { luisResult = await GetLuisResultAsync(utterance, httpClient, cancellationToken).ConfigureAwait(false); recognizerResult = BuildRecognizerResultFromLuisResult(luisResult, utterance); } var traceInfo = JObject.FromObject( new { recognizerResult, luisModel = new { ModelID = Application.ApplicationId, }, luisOptions = PredictionOptions, luisResult, }); await turnContext.TraceActivityAsync("LuisRecognizer", traceInfo, LuisTraceType, LuisTraceLabel, cancellationToken).ConfigureAwait(false); return(recognizerResult); }
private async Task SendErrorMessageAsync(ITurnContext turnContext, Exception exception) { try { // Send a message to the user. CultureInfo.CurrentUICulture = new CultureInfo(turnContext.Activity.Locale ?? "en-us"); await turnContext.SendActivityAsync(_templateManager.GenerateActivity(PhoneSharedResponses.ErrorMessage)); await turnContext.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : $"Phone Skill Error: {exception.Message} | {exception.StackTrace}")); _telemetryClient.TrackException(exception); // Send a trace activity, which will be displayed in the Bot Framework Emulator. // Note: we return the entire exception in the value property to help the developer; // this should not be done in production. await turnContext.TraceActivityAsync("OnTurnError Trace", exception.ToString(), "https://www.botframework.com/schemas/error", "TurnError"); } catch (Exception ex) { _logger.LogError(ex, $"Exception caught in SendErrorMessageAsync : {ex}"); } }
private async Task SendErrorMessageAsync(ITurnContext turnContext, Exception exception) { try { // Send a message to the user. var errorMessageText = "The skill encountered an error or bug."; var errorMessage = MessageFactory.Text(errorMessageText + Environment.NewLine + exception, errorMessageText, InputHints.IgnoringInput); await turnContext.SendActivityAsync(errorMessage); errorMessageText = "To continue to run this bot, please fix the bot source code."; errorMessage = MessageFactory.Text(errorMessageText, errorMessageText, InputHints.ExpectingInput); await turnContext.SendActivityAsync(errorMessage); // Send a trace activity, which will be displayed in the Bot Framework Emulator. // Note: we return the entire exception in the value property to help the developer; // this should not be done in production. await turnContext.TraceActivityAsync("OnTurnError Trace", exception.ToString(), "https://www.botframework.com/schemas/error", "TurnError"); } catch (Exception ex) { _logger.LogError(ex, $"Exception caught in SendErrorMessageAsync : {ex}"); } }
protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> context, CancellationToken cancellationToken) { var message = context.Activity; // To quickly test the bot after deploy to ensure the version we want is available. if (message.Text.ToLower().Equals("bot version")) { var version = typeof(SupportBot).Assembly.GetName().Version; var replyText = $"Art Gallery Support Assistant v{version?.Major}.{version?.Minor}.{version?.Build}.{version?.Revision}"; await context.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken); return; } // ******************************* Cognitive Services - Text Analysis API ******************************* // using var textAnalyticsClient = new TextAnalyticsClient(new TextAnalysisServiceClientCredentials(SubscriptionKeys.TextAnalysisServiceKey)) { Endpoint = "https://eastus.api.cognitive.microsoft.com/" }; var langResult = await textAnalyticsClient.DetectLanguageAsync(false, new LanguageBatchInput(new List <LanguageInput> { new LanguageInput(id: "1", text: message.Text) }), cancellationToken : cancellationToken); await context.TraceActivityAsync("OnMessageActivity Trace", langResult, "LanguageResult", cancellationToken : cancellationToken); var languageCode = string.Empty; foreach (var document in langResult.Documents) { // Pick the language with the highest score var bestLanguage = document.DetectedLanguages?.OrderByDescending(l => l.Score).FirstOrDefault(); if (string.IsNullOrEmpty(languageCode) && bestLanguage != null) { languageCode = bestLanguage.Iso6391Name.ToLower(); await context.TraceActivityAsync("OnMessageActivity Trace", languageCode, "string", cancellationToken : cancellationToken); } } // If we couldn't detect language if (string.IsNullOrEmpty(languageCode)) { var replyText = "We could not determine what language you're using. Please try again."; await context.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken); return; } // ******************************* Cognitive Services - Text Translation API ******************************* // var query = string.Empty; // If the detected language was not English, translate it before sending to LUIS if (languageCode != "en") { try { using var translationClient = new TextTranslationServiceClient(SubscriptionKeys.TextTranslationServiceKey); var result = await translationClient.TranslateAsync(message.Text, "en"); var translatedQuery = result?.Translations?.FirstOrDefault()?.Text; if (!string.IsNullOrEmpty(translatedQuery)) { query = translatedQuery; } } catch (Exception ex) { var replyText = $"RespondWithTranslatedReply Exception: {ex.Message}"; await context.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken); } } else { query = message.Text; } // ******************************* Cognitive Services - LUIS (Natural Language Understanding) API ******************************* // using var luisClient = new LUISRuntimeClient(new ApiKeyServiceClientCredentials(SubscriptionKeys.LuisPredictionKey)); luisClient.Endpoint = SubscriptionKeys.LuisEndpoint; // Prepare a prediction request var predictionRequest = new PredictionRequest { Query = query }; // Request a prediction, returns a PredictionResponse var predictionResponse = await luisClient.Prediction.GetSlotPredictionAsync( Guid.Parse(SubscriptionKeys.LuisAppId), "production", predictionRequest, verbose : true, showAllIntents : true, log : true, cancellationToken : cancellationToken); // You will get a full list of intents. For the purposes of this demo, we'll just use the highest scoring intent. var topScoringIntent = predictionResponse.Prediction.TopIntent; // Respond to the user depending on the detected intent of their query var respondedToQuery = await RespondWithEnglishAsync(context, topScoringIntent, languageCode, cancellationToken); // ******************************* Cognitive Services - Sentiment Analysis ******************************* // // Only evaluate sentiment if we've given a meaningful reply (and not connection or service error messages). if (respondedToQuery) { // Use Text Analytics Sentiment analysis var sentimentResult = await textAnalyticsClient.SentimentAsync( multiLanguageBatchInput : new MultiLanguageBatchInput(new List <MultiLanguageInput> { new MultiLanguageInput(id: "1", text: query, language: languageCode) }), cancellationToken : cancellationToken); if (sentimentResult?.Documents?.Count > 0) { await context.TraceActivityAsync("SentimentAsync Trace", sentimentResult.Documents[0], "SentimentBatchResultItem", cancellationToken : cancellationToken); SentimentBatchResultItem sentimentItem = sentimentResult.Documents[0]; // Use the sentiment score to determine if we need to react, the range is 0 (angriest) to 1 (happiest) await EvaluateAndRespondToSentimentAsync(context, sentimentItem, languageCode, cancellationToken); } } }
/// <summary> /// Creates a dialog stack and starts a dialog, pushing it onto the stack. /// </summary> /// <param name="dialog">The dialog to start.</param> /// <param name="turnContext">The context for the current turn of the conversation.</param> /// <param name="accessor">The <see cref="IStatePropertyAccessor{DialogState}"/> accessor /// with which to manage the state of the dialog stack.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static async Task RunAsync(this Dialog dialog, ITurnContext turnContext, IStatePropertyAccessor <DialogState> accessor, CancellationToken cancellationToken) { var dialogSet = new DialogSet(accessor) { TelemetryClient = dialog.TelemetryClient }; dialogSet.Add(dialog); var dialogContext = await dialogSet.CreateContextAsync(turnContext, cancellationToken).ConfigureAwait(false); if (turnContext.TurnState.Get <IIdentity>(BotAdapter.BotIdentityKey) is ClaimsIdentity claimIdentity && SkillValidation.IsSkillClaim(claimIdentity.Claims)) { // The bot is running as a skill. if (turnContext.Activity.Type == ActivityTypes.EndOfConversation && dialogContext.Stack.Any()) { // Handle remote cancellation request if we have something in the stack. var activeDialogContext = GetActiveDialogContext(dialogContext); var remoteCancelText = "Skill was canceled by a request from the host."; await turnContext.TraceActivityAsync($"{typeof(Dialog).Name}.RunAsync()", label : $"{remoteCancelText}", cancellationToken : cancellationToken).ConfigureAwait(false); // Send cancellation message to the top dialog in the stack to ensure all the parents are canceled in the right order. await activeDialogContext.CancelAllDialogsAsync(true, cancellationToken : cancellationToken).ConfigureAwait(false); } else { // Process a reprompt event sent from the parent. if (turnContext.Activity.Type == ActivityTypes.Event && turnContext.Activity.Name == DialogEvents.RepromptDialog && dialogContext.Stack.Any()) { await dialogContext.RepromptDialogAsync(cancellationToken).ConfigureAwait(false); return; } // Run the Dialog with the new message Activity and capture the results so we can send end of conversation if needed. var result = await dialogContext.ContinueDialogAsync(cancellationToken).ConfigureAwait(false); if (result.Status == DialogTurnStatus.Empty) { var startMessageText = $"Starting {dialog.Id}."; await turnContext.TraceActivityAsync($"{typeof(Dialog).Name}.RunAsync()", label : $"{startMessageText}", cancellationToken : cancellationToken).ConfigureAwait(false); result = await dialogContext.BeginDialogAsync(dialog.Id, null, cancellationToken).ConfigureAwait(false); } // Send end of conversation if it is completed or cancelled. if (result.Status == DialogTurnStatus.Complete || result.Status == DialogTurnStatus.Cancelled) { var endMessageText = $"Dialog {dialog.Id} has **completed**. Sending EndOfConversation."; await turnContext.TraceActivityAsync($"{typeof(Dialog).Name}.RunAsync()", label : $"{endMessageText}", value : result.Result, cancellationToken : cancellationToken).ConfigureAwait(false); // Send End of conversation at the end. var activity = new Activity(ActivityTypes.EndOfConversation) { Value = result.Result }; await turnContext.SendActivityAsync(activity, cancellationToken).ConfigureAwait(false); } } }
// Log Custom Trace public static async Task <Microsoft.Bot.Schema.ResourceResponse> LogCustomTrace(object trace, ITurnContext turnContext, string type, string service) { return(await turnContext.TraceActivityAsync(service, trace, type, type).ConfigureAwait(false)); }
/// <summary> /// Creates a dialog stack and starts a dialog, pushing it onto the stack. /// </summary> /// <param name="dialog">The dialog to start.</param> /// <param name="otherDialogs">Other dialogs to add to the stack other than starting dialog.</param> /// <param name="turnContext">The context for the current turn of the conversation.</param> /// <param name="accessor">The <see cref="IStatePropertyAccessor{DialogState}"/> accessor /// with which to manage the state of the dialog stack.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static async Task RunAsync(this Dialog dialog, IEnumerable <Dialog> otherDialogs, ITurnContext turnContext, IStatePropertyAccessor <DialogState> accessor, CancellationToken cancellationToken) { var dialogSet = new DialogSet(accessor) { TelemetryClient = dialog.TelemetryClient }; dialogSet.Add(dialog); if (otherDialogs != null) { foreach (var d in otherDialogs) { dialogSet.Add(d); } } var dialogContext = await dialogSet.CreateContextAsync(turnContext, cancellationToken).ConfigureAwait(false); // Handle EoC and Reprompt event from a parent bot (can be root bot to skill or skill to skill) if (IsFromParentToSkill(turnContext)) { // Handle remote cancellation request from parent. if (turnContext.Activity.Type == ActivityTypes.EndOfConversation) { if (!dialogContext.Stack.Any()) { // No dialogs to cancel, just return. return; } var activeDialogContext = GetActiveDialogContext(dialogContext); var remoteCancelText = "Skill was canceled through an EndOfConversation activity from the parent."; await turnContext.TraceActivityAsync($"{typeof(Dialog).Name}.RunAsync()", label : $"{remoteCancelText}", cancellationToken : cancellationToken).ConfigureAwait(false); // Send cancellation message to the top dialog in the stack to ensure all the parents are canceled in the right order. await activeDialogContext.CancelAllDialogsAsync(true, cancellationToken : cancellationToken).ConfigureAwait(false); return; } // Handle a reprompt event sent from the parent. if (turnContext.Activity.Type == ActivityTypes.Event && turnContext.Activity.Name == DialogEvents.RepromptDialog) { if (!dialogContext.Stack.Any()) { // No dialogs to reprompt, just return. return; } await dialogContext.RepromptDialogAsync(cancellationToken).ConfigureAwait(false); return; } } // Continue or start the dialog. var result = await dialogContext.ContinueDialogAsync(cancellationToken).ConfigureAwait(false); if (result.Status == DialogTurnStatus.Empty) { result = await dialogContext.BeginDialogAsync(dialog.Id, null, cancellationToken).ConfigureAwait(false); } // Skills should send EoC when the dialog completes. if (result.Status == DialogTurnStatus.Complete || result.Status == DialogTurnStatus.Cancelled) { if (SendEoCToParent(turnContext)) { var endMessageText = $"Dialog {dialog.Id} has **completed**. Sending EndOfConversation."; await turnContext.TraceActivityAsync($"{typeof(Dialog).Name}.RunAsync()", label : $"{endMessageText}", value : result.Result, cancellationToken : cancellationToken).ConfigureAwait(false); // Send End of conversation at the end. var code = result.Status == DialogTurnStatus.Complete ? EndOfConversationCodes.CompletedSuccessfully : EndOfConversationCodes.UserCancelled; var activity = new Activity(ActivityTypes.EndOfConversation) { Value = result.Result, Locale = turnContext.Activity.Locale, Code = code }; await turnContext.SendActivityAsync(activity, cancellationToken).ConfigureAwait(false); } } }
internal override async Task <RecognizerResult> RecognizeInternalAsync(ITurnContext turnContext, HttpClient httpClient, CancellationToken cancellationToken) { BotAssert.ContextNotNull(turnContext); if (turnContext.Activity == null || turnContext.Activity.Type != ActivityTypes.Message) { return(null); } var utterance = turnContext.Activity?.AsMessageActivity()?.Text; RecognizerResult recognizerResult; LuisResult luisResult = null; if (string.IsNullOrWhiteSpace(utterance)) { recognizerResult = new RecognizerResult { Text = utterance }; } else { var credentials = new ApiKeyServiceClientCredentials(Application.EndpointKey); var runtime = new LUISRuntimeClient(credentials, httpClient, false) { Endpoint = Application.Endpoint, }; luisResult = await runtime.Prediction.ResolveAsync( Application.ApplicationId, utterance, timezoneOffset : PredictionOptions.TimezoneOffset, verbose : PredictionOptions.IncludeAllIntents, staging : PredictionOptions.Staging, spellCheck : PredictionOptions.SpellCheck, bingSpellCheckSubscriptionKey : PredictionOptions.BingSpellCheckSubscriptionKey, log : PredictionOptions.Log ?? true, cancellationToken : cancellationToken).ConfigureAwait(false); recognizerResult = new RecognizerResult { Text = utterance, AlteredText = luisResult.AlteredQuery, Intents = LuisUtil.GetIntents(luisResult), Entities = LuisUtil.ExtractEntitiesAndMetadata(luisResult.Entities, luisResult.CompositeEntities, PredictionOptions.IncludeInstanceData ?? true, utterance), }; LuisUtil.AddProperties(luisResult, recognizerResult); if (IncludeAPIResults) { recognizerResult.Properties.Add("luisResult", luisResult); } } var traceInfo = JObject.FromObject( new { recognizerResult, luisModel = new { ModelID = Application.ApplicationId, }, luisOptions = PredictionOptions, luisResult, }); await turnContext.TraceActivityAsync("LuisRecognizer", traceInfo, LuisTraceType, LuisTraceLabel, cancellationToken).ConfigureAwait(false); return(recognizerResult); }
private async Task <RecognizerResult> RecognizeInternalAsync(ITurnContext turnContext, LuisPredictionOptions predictionOptions, Dictionary <string, string> telemetryProperties, Dictionary <string, double> telemetryMetrics, CancellationToken cancellationToken) { BotAssert.ContextNotNull(turnContext); if (turnContext.Activity.Type != ActivityTypes.Message) { return(null); } var options = predictionOptions ?? _predictionOptions; var utterance = turnContext.Activity?.AsMessageActivity()?.Text; RecognizerResult recognizerResult; JObject luisResponse = null; if (string.IsNullOrWhiteSpace(utterance)) { recognizerResult = new RecognizerResult { Text = utterance, Intents = new Dictionary <string, IntentScore>() { { string.Empty, new IntentScore() { Score = 1.0 } } }, Entities = new JObject(), }; } else { var uri = new UriBuilder(_application.Endpoint); // TODO: When the endpoint GAs, we will need to change this. I could make it an option, but other code is likely to need to change. uri.Path += $"luis/v3.0-preview/apps/{_application.ApplicationId}"; var query = AddParam(null, "verbose", options.IncludeInstanceData); query = AddParam(query, "log", options.Log); query = AddParam(query, "show-all-intents", options.IncludeAllIntents); uri.Query = query; var content = new JObject { { "query", utterance }, }; var queryOptions = new JObject { { "overridePredictions", options.PreferExternalEntities }, }; content.Add("options", queryOptions); var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; if (options.DynamicLists != null) { foreach (var list in options.DynamicLists) { list.Validate(); } content.Add("dynamicLists", (JArray)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(options.DynamicLists, settings))); } if (options.ExternalEntities != null) { foreach (var entity in options.ExternalEntities) { entity.Validate(); } content.Add("externalEntities", (JArray)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(options.ExternalEntities, settings))); } if (options.Version == null) { uri.Path += $"/slots/{options.Slot}/predict"; } else { uri.Path += $"/versions/{options.Version}/predict"; } var response = await DefaultHttpClient.PostAsync(uri.Uri, new StringContent(content.ToString(), System.Text.Encoding.UTF8, "application/json")).ConfigureAwait(false); response.EnsureSuccessStatusCode(); luisResponse = (JObject)JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false)); var prediction = (JObject)luisResponse["prediction"]; recognizerResult = new RecognizerResult { Text = utterance, AlteredText = prediction["alteredQuery"]?.Value <string>(), Intents = LuisUtil.GetIntents(prediction), Entities = LuisUtil.ExtractEntitiesAndMetadata(prediction), }; LuisUtil.AddProperties(prediction, recognizerResult); if (options.IncludeAPIResults) { recognizerResult.Properties.Add("luisResult", luisResponse); } } // Log telemetry OnRecognizerResult(recognizerResult, turnContext, telemetryProperties, telemetryMetrics); var traceInfo = JObject.FromObject( new { recognizerResult, luisModel = new { ModelID = _application.ApplicationId, }, luisOptions = options, luisResult = luisResponse, }); await turnContext.TraceActivityAsync("LuisRecognizer", traceInfo, LuisTraceType, LuisTraceLabel, cancellationToken).ConfigureAwait(false); return(recognizerResult); }
private async Task <RecognizerResult> RecognizeAsync(ITurnContext turnContext, string utterance, LuisV3.LuisPredictionOptions options, HttpClient httpClient, CancellationToken cancellationToken) { RecognizerResult recognizerResult; JObject luisResponse = null; if (string.IsNullOrWhiteSpace(utterance)) { recognizerResult = new RecognizerResult { Text = utterance }; } else { var uri = BuildUri(options); var content = BuildRequestBody(utterance, options); httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Application.EndpointKey); var response = await httpClient.PostAsync(uri.Uri, new StringContent(content.ToString(), System.Text.Encoding.UTF8, "application/json")).ConfigureAwait(false); response.EnsureSuccessStatusCode(); httpClient.DefaultRequestHeaders.Remove("Ocp-Apim-Subscription-Key"); luisResponse = (JObject)JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false)); var prediction = (JObject)luisResponse["prediction"]; recognizerResult = new RecognizerResult(); recognizerResult.Text = utterance; recognizerResult.AlteredText = prediction["alteredQuery"]?.Value <string>(); recognizerResult.Intents = LuisV3.LuisUtil.GetIntents(prediction); recognizerResult.Entities = LuisV3.LuisUtil.ExtractEntitiesAndMetadata(prediction); LuisV3.LuisUtil.AddProperties(prediction, recognizerResult); if (IncludeAPIResults) { recognizerResult.Properties.Add("luisResult", luisResponse); } if (PredictionOptions.IncludeInstanceData) { var instanceObject = recognizerResult.Entities["$instance"]; if (instanceObject == null) { recognizerResult.Entities.Add("$instance", new JObject()); } } } var traceInfo = JObject.FromObject( new { recognizerResult, luisModel = new { ModelID = Application.ApplicationId, }, luisOptions = options, luisResult = luisResponse, }); await turnContext.TraceActivityAsync("LuisRecognizer", traceInfo, LuisTraceType, LuisTraceLabel, cancellationToken).ConfigureAwait(false); return(recognizerResult); }
private async Task <RecognizerResult> RecognizeInternalAsync(ITurnContext turnContext, LuisPredictionOptions predictionOptions, Dictionary <string, string> telemetryProperties, Dictionary <string, double> telemetryMetrics, CancellationToken cancellationToken) { var luisPredictionOptions = predictionOptions == null ? _options : MergeDefaultOptionsWithProvidedOptions(_options, predictionOptions); BotAssert.ContextNotNull(turnContext); if (turnContext.Activity.Type != ActivityTypes.Message) { return(null); } var utterance = turnContext.Activity?.AsMessageActivity()?.Text; RecognizerResult recognizerResult; LuisResult luisResult = null; if (string.IsNullOrWhiteSpace(utterance)) { recognizerResult = new RecognizerResult { Text = utterance, Intents = new Dictionary <string, IntentScore>() { { string.Empty, new IntentScore() { Score = 1.0 } } }, Entities = new JObject(), }; } else { luisResult = await _runtime.Prediction.ResolveAsync( _application.ApplicationId, utterance, timezoneOffset: luisPredictionOptions.TimezoneOffset, verbose: luisPredictionOptions.IncludeAllIntents, staging: luisPredictionOptions.Staging, spellCheck: luisPredictionOptions.SpellCheck, bingSpellCheckSubscriptionKey : luisPredictionOptions.BingSpellCheckSubscriptionKey, log : luisPredictionOptions.Log ?? true, cancellationToken : cancellationToken).ConfigureAwait(false); recognizerResult = new RecognizerResult { Text = utterance, AlteredText = luisResult.AlteredQuery, Intents = LuisUtil.GetIntents(luisResult), Entities = LuisUtil.ExtractEntitiesAndMetadata(luisResult.Entities, luisResult.CompositeEntities, luisPredictionOptions.IncludeInstanceData ?? true, utterance), }; LuisUtil.AddProperties(luisResult, recognizerResult); if (_includeApiResults) { recognizerResult.Properties.Add("luisResult", luisResult); } } // Log telemetry await OnRecognizerResultAsync(recognizerResult, turnContext, telemetryProperties, telemetryMetrics, cancellationToken).ConfigureAwait(false); var traceInfo = JObject.FromObject( new { recognizerResult, luisModel = new { ModelID = _application.ApplicationId, }, luisOptions = luisPredictionOptions, luisResult, }); await turnContext.TraceActivityAsync("LuisRecognizer", traceInfo, LuisTraceType, LuisTraceLabel, cancellationToken).ConfigureAwait(false); return(recognizerResult); }