Esempio n. 1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LuisPredictionOptions"/> class from an existing instance.
 /// </summary>
 /// <param name="other">Source of values.</param>
 public LuisPredictionOptions(LuisPredictionOptions other)
 {
     IncludeAllIntents   = other.IncludeAllIntents;
     IncludeAPIResults   = other.IncludeAPIResults;
     IncludeInstanceData = other.IncludeInstanceData;
     Log                    = other.Log;
     DynamicLists           = other.DynamicLists;
     ExternalEntities       = other.ExternalEntities;
     PreferExternalEntities = other.PreferExternalEntities;
     Slot                   = other.Slot;
     Version                = other.Version;
 }
        /// <summary>
        /// Return results of the analysis (Suggested actions and intents).
        /// </summary>
        /// <typeparam name="T">The recognition result type.</typeparam>
        /// <param name="turnContext">Context object containing information for a single turn of conversation with a user.</param>
        /// <param name="predictionOptions">A <see cref="LuisPredictionOptions"/> instance to be used by the call.
        /// This parameter gets merged with the default <see cref="LuisPredictionOptions"/> passed in the constructor.</param>
        /// <param name="telemetryProperties">Additional properties to be logged to telemetry with the LuisResult event.</param>
        /// <param name="telemetryMetrics">Additional metrics to be logged to telemetry with the LuisResult event.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>The LUIS results of the analysis of the current message text in the current turn's context activity.</returns>
        public virtual async Task <T> RecognizeAsync <T>(
            ITurnContext turnContext,
            LuisPredictionOptions predictionOptions         = null,
            Dictionary <string, string> telemetryProperties = null,
            Dictionary <string, double> telemetryMetrics    = null,
            CancellationToken cancellationToken             = default)
            where T : IRecognizerConvert, new()
        {
            var result = new T();

            result.Convert(await RecognizeInternalAsync(turnContext, predictionOptions, telemetryProperties, telemetryMetrics, cancellationToken).ConfigureAwait(false));
            return(result);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="LuisRecognizer"/> class.
        /// </summary>
        /// <param name="application">The LUIS application to use to recognize text.</param>
        /// <param name="recognizerOptions">(Optional) Options for the created recognizer.</param>
        /// <param name="predictionOptions">(Optional) The default LUIS prediction options to use.</param>
        public LuisRecognizer(LuisApplication application, LuisRecognizerOptions recognizerOptions = null, LuisPredictionOptions predictionOptions = null)
        {
            recognizerOptions  = recognizerOptions ?? new LuisRecognizerOptions();
            _application       = application ?? throw new ArgumentNullException(nameof(application));
            _predictionOptions = predictionOptions ?? new LuisPredictionOptions();

            TelemetryClient        = recognizerOptions.TelemetryClient;
            LogPersonalInformation = recognizerOptions.LogPersonalInformation;

            var delegatingHandler = new LuisV2.LuisDelegatingHandler();
            var httpClientHandler = recognizerOptions.HttpClient ?? CreateRootHandler();
            var currentHandler    = CreateHttpHandlerPipeline(httpClientHandler, delegatingHandler);

            DefaultHttpClient = new HttpClient(currentHandler, false)
            {
                Timeout = recognizerOptions.Timeout,
            };

            DefaultHttpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", _application.EndpointKey);
        }
        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);
        }
 /// <summary>
 /// Runs an utterance through a recognizer and returns a generic recognizer result.
 /// </summary>
 /// <param name="turnContext">Turn context.</param>
 /// <param name="predictionOptions">A <see cref="LuisPredictionOptions"/> instance to be used by the call.
 /// This parameter gets merged with the default <see cref="LuisPredictionOptions"/> passed in the constructor.</param>
 /// <param name="cancellationToken">Cancellation token.</param>
 /// <returns>Analysis of utterance.</returns>
 public virtual async Task <RecognizerResult> RecognizeAsync(ITurnContext turnContext, LuisPredictionOptions predictionOptions, CancellationToken cancellationToken)
 => await RecognizeInternalAsync(turnContext, predictionOptions, null, null, cancellationToken).ConfigureAwait(false);