/// <summary>
        /// BindOptions - evaluate expressions in options.
        /// </summary>
        /// <param name="dc">dialog context.</param>
        /// <param name="options">options to bind.</param>
        /// <returns>merged options with expressions bound to values.</returns>
        protected virtual object BindOptions(DialogContext dc, object options)
        {
            // binding options are static definition of options with overlay of passed in options);
            var bindingOptions = (JObject)ObjectPath.Merge(this.Options.GetValue(dc.State), options ?? new JObject());
            var boundOptions   = new JObject();

            foreach (var binding in bindingOptions)
            {
                JToken value = null;

                // evaluate the value
                var(val, error) = new ValueExpression(binding.Value).TryGetValue(dc.State);

                if (error != null)
                {
                    throw new Exception(error);
                }

                if (val != null)
                {
                    value = JToken.FromObject(val).DeepClone();
                }

                value = value?.ReplaceJTokenRecursively(dc.State);

                // and store in options as the result
                ObjectPath.SetPathValue(boundOptions, binding.Key, value);
            }

            return(boundOptions);
        }
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next,
                                      CancellationToken cancellationToken = new CancellationToken())
        {
            if (_internetProtocolMiddlewareSettings.IsInternetProtocolEnable && turnContext.Activity.Type == ActivityTypes.Message &&
                !string.IsNullOrEmpty(turnContext.Activity.Text))
            {
                var culture = turnContext.Activity.Locale ?? _internetProtocolMiddlewareSettings.Locale;

                List <ModelResult> modelResults = null;

                switch (_internetProtocolMiddlewareSettings.InternetProtocolType)
                {
                case InternetProtocolType.IpAddress:
                    modelResults = SequenceRecognizer.RecognizeIpAddress(turnContext.Activity.Text, culture);
                    break;

                case InternetProtocolType.Url:
                    modelResults = SequenceRecognizer.RecognizeURL(turnContext.Activity.Text, culture);
                    break;
                }

                if (modelResults?.Count > 0)
                {
                    var value = modelResults[0].Resolution["value"].ToString();

                    ObjectPath.SetPathValue(turnContext.TurnState, _internetProtocolMiddlewareSettings.Property, value);
                }
            }

            await next(cancellationToken);
        }
        public void SimpleMemoryScopesTest()
        {
            var dc  = new DialogContext(new DialogSet(), new TurnContext(new TestAdapter(), new Schema.Activity()), (DialogState) new DialogState());
            var dsm = new DialogStateManager(dc);

            foreach (var memoryScope in DialogStateManager.MemoryScopes.Where(ms => !(ms is ThisMemoryScope || ms is DialogMemoryScope || ms is ClassMemoryScope)))
            {
                var memory = memoryScope.GetMemory(dc);
                Assert.IsNotNull(memory, "should get memory without any set");
                ObjectPath.SetPathValue(memory, "test", 15);
                memory = memoryScope.GetMemory(dc);
                Assert.AreEqual(15, ObjectPath.GetPathValue <int>(memory, "test"), "Should roundtrip memory");
                ObjectPath.SetPathValue(memory, "test", 25);
                memory = memoryScope.GetMemory(dc);
                Assert.AreEqual(25, ObjectPath.GetPathValue <int>(memory, "test"), "Should roundtrip memory2");
                memory = memoryScope.GetMemory(dc);
                ObjectPath.SetPathValue(memory, "source", "destination");
                ObjectPath.SetPathValue(memory, "{source}", 24);
                Assert.AreEqual(24, ObjectPath.GetPathValue <int>(memory, "{source}"), "Roundtrip computed path");
                ObjectPath.RemovePathValue(memory, "{source}");
                Assert.AreEqual(false, ObjectPath.TryGetPathValue <int>(memory, "{source}", out var _), "Removed computed path");
                ObjectPath.RemovePathValue(memory, "source");
                Assert.AreEqual(false, ObjectPath.TryGetPathValue <int>(memory, "{source}", out var _), "No computed path");
            }
        }
 public async Task SimpleMemoryScopesTest()
 {
     await CreateDialogContext(async (dc, ct) =>
     {
         var dsm = dc.State as DialogStateManager;
         foreach (var memoryScope in dsm.Configuration.MemoryScopes.Where(ms => !(ms is ThisMemoryScope ||
                                                                                  ms is DialogMemoryScope ||
                                                                                  ms is ClassMemoryScope ||
                                                                                  ms is DialogClassMemoryScope ||
                                                                                  ms is DialogContextMemoryScope)))
         {
             var memory = memoryScope.GetMemory(dc);
             Assert.NotNull(memory);
             ObjectPath.SetPathValue(memory, "test", 15);
             memory = memoryScope.GetMemory(dc);
             Assert.Equal(15, ObjectPath.GetPathValue <int>(memory, "test"));
             ObjectPath.SetPathValue(memory, "test", 25);
             memory = memoryScope.GetMemory(dc);
             Assert.Equal(25, ObjectPath.GetPathValue <int>(memory, "test"));
             memory = memoryScope.GetMemory(dc);
             ObjectPath.SetPathValue(memory, "source", "destination");
             ObjectPath.SetPathValue(memory, "{source}", 24);
             Assert.Equal(24, ObjectPath.GetPathValue <int>(memory, "{source}"));
             ObjectPath.RemovePathValue(memory, "{source}");
             Assert.False(ObjectPath.TryGetPathValue <int>(memory, "{source}", out var _));
             ObjectPath.RemovePathValue(memory, "source");
             Assert.False(ObjectPath.TryGetPathValue <int>(memory, "{source}", out var _));
         }
     }).StartTestAsync();
 }
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next,
                                      CancellationToken cancellationToken = new CancellationToken())
        {
            if (_mediaMiddlewareSettings.IsSocialMediaEnable && turnContext.Activity.Type == ActivityTypes.Message &&
                !string.IsNullOrEmpty(turnContext.Activity.Text))
            {
                var culture = turnContext.Activity.Locale ?? _mediaMiddlewareSettings.Locale;

                List <ModelResult> modelResults = null;

                switch (_mediaMiddlewareSettings.MediaType)
                {
                case SocialMediaType.Mention:
                    modelResults = SequenceRecognizer.RecognizeMention(turnContext.Activity.Text, culture);
                    break;

                case SocialMediaType.Hashtag:
                    modelResults = SequenceRecognizer.RecognizeHashtag(turnContext.Activity.Text, culture);
                    break;
                }

                if (modelResults?.Count > 0)
                {
                    var value = modelResults[0].Resolution["value"].ToString();

                    ObjectPath.SetPathValue(turnContext.TurnState, _mediaMiddlewareSettings.Property, value);
                }
            }

            await next(cancellationToken);
        }
        public void RemovePathValue()
        {
            var test = new Dictionary <string, object>();

            ObjectPath.SetPathValue(test, "x.y.z", 15);
            ObjectPath.SetPathValue(test, "x.p", "hello");
            ObjectPath.SetPathValue(test, "foo", new { Bar = 15, Blat = "yo" });
            ObjectPath.SetPathValue(test, "x.a[1]", "yabba");
            ObjectPath.SetPathValue(test, "x.a[0]", "dabba");

            ObjectPath.RemovePathValue(test, "x.y.z");
            try
            {
                ObjectPath.GetPathValue <int>(test, "x.y.z");
                throw new XunitException("should have throw exception");
            }
            catch
            {
            }

            Assert.Null(ObjectPath.GetPathValue <string>(test, "x.y.z", null));
            Assert.Equal(99, ObjectPath.GetPathValue <int>(test, "x.y.z", 99));
            Assert.False(ObjectPath.TryGetPathValue <string>(test, "x.y.z", out var value));
            ObjectPath.RemovePathValue(test, "x.a[1]");
            Assert.False(ObjectPath.TryGetPathValue <string>(test, "x.a[1]", out string value2));
            Assert.True(ObjectPath.TryGetPathValue <string>(test, "x.a[0]", out value2));
            Assert.Equal("dabba", value2);
        }
        /// <summary>
        /// Called when the dialog is started and pushed onto the dialog stack.
        /// </summary>
        /// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
        /// <param name="options">Optional, initial information to pass to the dialog.</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>
        /// <remarks>If the task is successful, the result indicates whether the dialog is still
        /// active after the turn has been processed by the dialog.
        ///
        /// You can use the <paramref name="options"/> parameter to include the QnA Maker context data,
        /// which represents context from the previous query. To do so, the value should include a
        /// `context` property of type <see cref="QnAResponseContext"/>.</remarks>
        /// <seealso cref="DialogContext.BeginDialogAsync(string, object, CancellationToken)"/>
        public override async Task <DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            if (dc.Context?.Activity?.Type != ActivityTypes.Message)
            {
                return(EndOfTurn);
            }

            var dialogOptions = new QnAMakerDialogOptions()
            {
                QnAMakerOptions = await GetQnAMakerOptionsAsync(dc).ConfigureAwait(false),
                ResponseOptions = await GetQnAResponseOptionsAsync(dc).ConfigureAwait(false)
            };

            if (options != null)
            {
                dialogOptions = ObjectPath.Assign <QnAMakerDialogOptions>(dialogOptions, options);
            }

            ObjectPath.SetPathValue(dc.ActiveDialog.State, Options, dialogOptions);

            return(await base.BeginDialogAsync(dc, dialogOptions, cancellationToken).ConfigureAwait(false));
        }
Exemple #8
0
 public async Task SimpleMemoryScopesTest()
 {
     await CreateDialogContext(async (dc, ct) =>
     {
         var dsm = dc.State as DialogStateManager;
         foreach (var memoryScope in dsm.Configuration.MemoryScopes.Where(ms => !(ms is ThisMemoryScope || ms is DialogMemoryScope || ms is ClassMemoryScope || ms is DialogClassMemoryScope)))
         {
             var memory = memoryScope.GetMemory(dc);
             Assert.IsNotNull(memory, "should get memory without any set");
             ObjectPath.SetPathValue(memory, "test", 15);
             memory = memoryScope.GetMemory(dc);
             Assert.AreEqual(15, ObjectPath.GetPathValue <int>(memory, "test"), "Should roundtrip memory");
             ObjectPath.SetPathValue(memory, "test", 25);
             memory = memoryScope.GetMemory(dc);
             Assert.AreEqual(25, ObjectPath.GetPathValue <int>(memory, "test"), "Should roundtrip memory2");
             memory = memoryScope.GetMemory(dc);
             ObjectPath.SetPathValue(memory, "source", "destination");
             ObjectPath.SetPathValue(memory, "{source}", 24);
             Assert.AreEqual(24, ObjectPath.GetPathValue <int>(memory, "{source}"), "Roundtrip computed path");
             ObjectPath.RemovePathValue(memory, "{source}");
             Assert.AreEqual(false, ObjectPath.TryGetPathValue <int>(memory, "{source}", out var _), "Removed computed path");
             ObjectPath.RemovePathValue(memory, "source");
             Assert.AreEqual(false, ObjectPath.TryGetPathValue <int>(memory, "{source}", out var _), "No computed path");
         }
     }).StartTestAsync();
 }
        private void AssertGetSetValueType <T>(object test, T val)
        {
            ObjectPath.SetPathValue(test, val.GetType().Name, val);
            var result = ObjectPath.GetPathValue <T>(test, typeof(T).Name);

            Assert.Equal(val, result);
            Assert.Equal(val.GetType(), result.GetType());
        }
Exemple #10
0
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (turnContext.Activity.Type is ActivityTypes.Message && _creds.IsEnabled == true)
            {
                ObjectPath.SetPathValue(turnContext.TurnState, "turn.Sentiment", await turnContext.Activity.Text.Sentiment(_creds.APIKey, _creds.EndpointUrl));
            }

            await next(cancellationToken);
        }
        public void SetPathValue()
        {
            const string dateISO = "2021-11-30T23:59:59:000Z";
            var          test    = new Dictionary <string, object>();

            ObjectPath.SetPathValue(test, "x.y.z", 15);
            ObjectPath.SetPathValue(test, "x.p", "hello");
            ObjectPath.SetPathValue(test, "foo", new { Bar = 15, Blat = "yo" });
            ObjectPath.SetPathValue(test, "x.a[1]", "yabba");
            ObjectPath.SetPathValue(test, "x.a[0]", "dabba");
            ObjectPath.SetPathValue(test, "null", null);
            ObjectPath.SetPathValue(test, "enum", TypeCode.Empty);
            ObjectPath.SetPathValue(test, "date.string.iso", dateISO);
            ObjectPath.SetPathValue(test, "date.string.jtoken.iso", new JValue(dateISO));
            ObjectPath.SetPathValue(test, "date.object", new { iso = dateISO });
            ObjectPath.SetPathValue(test, "date.object.jtoken", JToken.FromObject(new { iso = dateISO }));

            Assert.Equal(15, ObjectPath.GetPathValue <int>(test, "x.y.z"));
            Assert.Equal("hello", ObjectPath.GetPathValue <string>(test, "x.p"));
            Assert.Equal(15, ObjectPath.GetPathValue <int>(test, "foo.bar"));
            Assert.Equal("yo", ObjectPath.GetPathValue <string>(test, "foo.Blat"));
            Assert.False(ObjectPath.TryGetPathValue <string>(test, "foo.Blatxxx", out var value));
            Assert.True(ObjectPath.TryGetPathValue <string>(test, "x.a[1]", out var value2));
            Assert.Equal("yabba", value2);
            Assert.True(ObjectPath.TryGetPathValue <string>(test, "x.a[0]", out value2));
            Assert.Equal("dabba", value2);
            Assert.False(ObjectPath.TryGetPathValue <object>(test, "null", out var nullValue));
            Assert.Equal(TypeCode.Empty, ObjectPath.GetPathValue <TypeCode>(test, "enum"));
            Assert.Equal(dateISO, ObjectPath.GetPathValue <string>(test, "date.string.iso"));
            Assert.Equal(dateISO, ObjectPath.GetPathValue <string>(test, "date.string.jtoken.iso"));
            Assert.Equal(dateISO, ObjectPath.GetPathValue <string>(test, "date.object.iso"));
            Assert.Equal(dateISO, ObjectPath.GetPathValue <string>(test, "date.object.jtoken.iso"));

            // value type tests
#pragma warning disable SA1121 // Use built-in type alias
            AssertGetSetValueType(test, true);
            AssertGetSetValueType(test, DateTime.UtcNow);
            AssertGetSetValueType(test, DateTimeOffset.UtcNow);
            AssertGetSetValueType(test, Byte.MaxValue);
            AssertGetSetValueType(test, Int16.MaxValue);
            AssertGetSetValueType(test, Int32.MaxValue);
            AssertGetSetValueType(test, Int64.MaxValue);
            AssertGetSetValueType(test, UInt16.MaxValue);
            AssertGetSetValueType(test, UInt32.MaxValue);
            AssertGetSetValueType(test, UInt64.MaxValue);
            AssertGetSetValueType(test, Single.MaxValue);
            AssertGetSetValueType(test, Decimal.MaxValue);
            AssertGetSetValueType(test, Double.MaxValue);
#pragma warning restore SA1121 // Use built-in type alias
        }
        /// <summary>
        /// BindOptions - evaluate expressions in options.
        /// </summary>
        /// <param name="dc">dialog context.</param>
        /// <param name="options">options to bind.</param>
        /// <returns>merged options with expressions bound to values.</returns>
        protected virtual object BindOptions(DialogContext dc, object options)
        {
            // binding options are static definition of options with overlay of passed in options);
            var bindingOptions = (JObject)ObjectPath.Merge(this.Options.GetValue(dc.State), options ?? new JObject());
            var boundOptions   = new JObject();

            foreach (var binding in bindingOptions)
            {
                // evaluate the value
                var value = new ValueExpression(binding.Value).EvaluateExpression(dc.State);

                // and store in options as the result
                ObjectPath.SetPathValue(boundOptions, binding.Key, value);
            }

            return(boundOptions);
        }
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next,
                                      CancellationToken cancellationToken = new CancellationToken())
        {
            var lastChatTime = await LastAccssedTimeProperty
                               .GetAsync(turnContext, () => DateTime.UtcNow, cancellationToken).ConfigureAwait(false);

            if (ExpireAfterSeconds > 0)
            {
                var timeInterval = DateTime.UtcNow - lastChatTime;

                if (timeInterval >= TimeSpan.FromSeconds(ExpireAfterSeconds))
                {
                    // Clear state.
                    await _conversationState.ClearStateAsync(turnContext, cancellationToken).ConfigureAwait(false);

                    var conversationExpire = new
                    {
                        TimeDelay           = timeInterval,
                        ExceptedWaitingTime = ExpireAfterSeconds,
                        ReceivedType        = turnContext.Activity.Type
                    };


                    turnContext.Activity.Type = ConversationActivity.ActivityName;


                    var expireDetails = JsonConvert.SerializeObject(conversationExpire);
                    ObjectPath.SetPathValue(turnContext.TurnState, "turn.expire", JObject.Parse(expireDetails));
                }
            }


            // Set LastAccessedTime to the current time.
            await LastAccssedTimeProperty.SetAsync(turnContext, DateTime.UtcNow, cancellationToken)
            .ConfigureAwait(false);

            // Save any state changes that might have occurred during the turn.
            await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken)
            .ConfigureAwait(false);

            await next(cancellationToken);
        }
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next,
                                      CancellationToken cancellationToken = new CancellationToken())
        {
            if (_emailMiddlewareSettings.IsEmailEnable && turnContext.Activity.Type == ActivityTypes.Message && !string.IsNullOrEmpty(turnContext.Activity.Text))
            {
                var culture = turnContext.Activity.Locale ?? _emailMiddlewareSettings.Locale;

                var recognizeEmail = SequenceRecognizer.RecognizeEmail(turnContext.Activity.Text, culture);
                if (recognizeEmail?.Count > 0)
                {
                    var value = recognizeEmail[0].Resolution["value"].ToString();

                    if (!string.IsNullOrEmpty(value))
                    {
                        ObjectPath.SetPathValue(turnContext.TurnState, _emailMiddlewareSettings.Property, value);
                    }
                }
            }
            await next(cancellationToken);
        }
Exemple #15
0
        public void SetPathValue()
        {
            Dictionary <string, object> test = new Dictionary <string, object>();

            ObjectPath.SetPathValue(test, "x.y.z", 15);
            ObjectPath.SetPathValue(test, "x.p", "hello");
            ObjectPath.SetPathValue(test, "foo", new { Bar = 15, Blat = "yo" });
            ObjectPath.SetPathValue(test, "x.a[1]", "yabba");
            ObjectPath.SetPathValue(test, "x.a[0]", "dabba");

            Assert.AreEqual(15, ObjectPath.GetPathValue <int>(test, "x.y.z"));
            Assert.AreEqual("hello", ObjectPath.GetPathValue <string>(test, "x.p"));
            Assert.AreEqual(15, ObjectPath.GetPathValue <int>(test, "foo.bar"));
            Assert.AreEqual("yo", ObjectPath.GetPathValue <string>(test, "foo.Blat"));
            Assert.IsFalse(ObjectPath.TryGetPathValue <string>(test, "foo.Blatxxx", out var value));
            Assert.IsTrue(ObjectPath.TryGetPathValue <string>(test, "x.a[1]", out var value2));
            Assert.AreEqual("yabba", value2);
            Assert.IsTrue(ObjectPath.TryGetPathValue <string>(test, "x.a[0]", out value2));
            Assert.AreEqual("dabba", value2);
        }
        public void SetPathValue()
        {
            Dictionary <string, object> test = new Dictionary <string, object>();

            ObjectPath.SetPathValue(test, "x.y.z", 15);
            ObjectPath.SetPathValue(test, "x.p", "hello");
            ObjectPath.SetPathValue(test, "foo", new { Bar = 15, Blat = "yo" });
            ObjectPath.SetPathValue(test, "x.a[1]", "yabba");
            ObjectPath.SetPathValue(test, "x.a[0]", "dabba");
            ObjectPath.SetPathValue(test, "null", null);
            ObjectPath.SetPathValue(test, "enum", TypeCode.Empty);

            Assert.AreEqual(15, ObjectPath.GetPathValue <int>(test, "x.y.z"));
            Assert.AreEqual("hello", ObjectPath.GetPathValue <string>(test, "x.p"));
            Assert.AreEqual(15, ObjectPath.GetPathValue <int>(test, "foo.bar"));
            Assert.AreEqual("yo", ObjectPath.GetPathValue <string>(test, "foo.Blat"));
            Assert.IsFalse(ObjectPath.TryGetPathValue <string>(test, "foo.Blatxxx", out var value));
            Assert.IsTrue(ObjectPath.TryGetPathValue <string>(test, "x.a[1]", out var value2));
            Assert.AreEqual("yabba", value2);
            Assert.IsTrue(ObjectPath.TryGetPathValue <string>(test, "x.a[0]", out value2));
            Assert.AreEqual("dabba", value2);
            Assert.IsFalse(ObjectPath.TryGetPathValue <object>(test, "null", out var nullValue));
            Assert.AreEqual(TypeCode.Empty, ObjectPath.GetPathValue <TypeCode>(test, "enum"));

            // value type tests
#pragma warning disable SA1121 // Use built-in type alias
            AssertGetSetValueType(test, true);
            AssertGetSetValueType(test, DateTime.UtcNow);
            AssertGetSetValueType(test, DateTimeOffset.UtcNow);
            AssertGetSetValueType(test, Byte.MaxValue);
            AssertGetSetValueType(test, Int16.MaxValue);
            AssertGetSetValueType(test, Int32.MaxValue);
            AssertGetSetValueType(test, Int64.MaxValue);
            AssertGetSetValueType(test, UInt16.MaxValue);
            AssertGetSetValueType(test, UInt32.MaxValue);
            AssertGetSetValueType(test, UInt64.MaxValue);
            AssertGetSetValueType(test, Single.MaxValue);
            AssertGetSetValueType(test, Decimal.MaxValue);
            AssertGetSetValueType(test, Double.MaxValue);
#pragma warning restore SA1121 // Use built-in type alias
        }
Exemple #17
0
        protected object BindOptions(DialogContext dc, object options)
        {
            // binding options are static definition of options with overlay of passed in options);
            var bindingOptions = (JObject)ObjectPath.Merge(this.Options.GetValue(dc.State), options ?? new JObject());
            var boundOptions   = new JObject();

            foreach (var binding in bindingOptions)
            {
                // evalute the value
                var(value, error) = new ValueExpression(binding.Value).TryGetValue(dc.State);

                if (error != null)
                {
                    throw new Exception(error);
                }

                // and store in options as the result
                ObjectPath.SetPathValue(boundOptions, binding.Key, value);
            }

            return(boundOptions);
        }
        private async Task <DialogTurnResult> CheckForMultiTurnPromptAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var dialogOptions = ObjectPath.GetPathValue <QnAMakerDialogOptions>(stepContext.ActiveDialog.State, Options);

            if (stepContext.Result is List <QueryResult> response && response.Count > 0)
            {
                // -Check if context is present and prompt exists
                // -If yes: Add reverse index of prompt display name and its corresponding QnA ID
                // -Set PreviousQnAId as answer.Id
                // -Display card for the prompt
                // -Wait for the reply
                // -If no: Skip to next step

                var answer = response.First();

                if (answer.Context != null && answer.Context.Prompts.Count() > 0)
                {
                    var previousContextData = ObjectPath.GetPathValue(stepContext.ActiveDialog.State, QnAContextData, new Dictionary <string, int>());
                    var previousQnAId       = ObjectPath.GetPathValue <int>(stepContext.ActiveDialog.State, PreviousQnAId, 0);

                    foreach (var prompt in answer.Context.Prompts)
                    {
                        previousContextData[prompt.DisplayText] = prompt.QnaId;
                    }

                    ObjectPath.SetPathValue(stepContext.ActiveDialog.State, QnAContextData, previousContextData);
                    ObjectPath.SetPathValue(stepContext.ActiveDialog.State, PreviousQnAId, answer.Id);
                    ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions);

                    // Get multi-turn prompts card activity.
                    var message = QnACardBuilder.GetQnAPromptsCard(answer, dialogOptions.ResponseOptions.CardNoMatchText);
                    await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);

                    return(new DialogTurnResult(DialogTurnStatus.Waiting));
                }
            }

            return(await stepContext.NextAsync(stepContext.Result, cancellationToken).ConfigureAwait(false));
        }
        public override async Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken, Dictionary <string, string> telemetryProperties = null, Dictionary <string, double> telemetryMetrics = null)
        {
            var dcState = dialogContext.GetState();

            // Identify matched intents
            var recognizerResult = new RecognizerResult()
            {
                Text    = activity.Text,
                Intents = new Dictionary <string, IntentScore>(),
            };

            if (string.IsNullOrEmpty(activity.Text))
            {
                recognizerResult.Intents.Add("None", new IntentScore());
                return(recognizerResult);
            }

            List <Metadata> filters = new List <Metadata>();

            if (IncludeDialogNameInMetadata.GetValue(dcState))
            {
                filters.Add(new Metadata()
                {
                    Name = "dialogName", Value = dialogContext.ActiveDialog.Id
                });
            }

            // if there is $qna.metadata set add to filters
            var externalMetadata = this.Metadata?.GetValue(dcState);

            if (externalMetadata != null)
            {
                filters.AddRange(externalMetadata);
            }

            // Calling QnAMaker to get response.
            var qnaClient = await GetQnAMakerClientAsync(dialogContext).ConfigureAwait(false);

            var answers = await qnaClient.GetAnswersAsync(
                dialogContext.Context,
                new QnAMakerOptions
            {
                Context        = this.Context?.GetValue(dcState),
                ScoreThreshold = this.Threshold.GetValue(dcState),
                StrictFilters  = filters.ToArray(),
                Top            = this.Top.GetValue(dcState),
                QnAId          = this.QnAId.GetValue(dcState),
                RankerType     = this.RankerType.GetValue(dcState),
                IsTest         = this.IsTest
            },
                null).ConfigureAwait(false);

            if (answers.Any())
            {
                QueryResult topAnswer = null;
                foreach (var answer in answers)
                {
                    if ((topAnswer == null) || (answer.Score > topAnswer.Score))
                    {
                        topAnswer = answer;
                    }
                }

                if (topAnswer.Answer.Trim().ToLower().StartsWith(IntentPrefix))
                {
                    recognizerResult.Intents.Add(topAnswer.Answer.Trim().Substring(IntentPrefix.Length).Trim(), new IntentScore()
                    {
                        Score = topAnswer.Score
                    });
                }
                else
                {
                    recognizerResult.Intents.Add(QnAMatchIntent, new IntentScore()
                    {
                        Score = topAnswer.Score
                    });
                }

                var answerArray = new JArray();
                answerArray.Add(topAnswer.Answer);
                ObjectPath.SetPathValue(recognizerResult, "entities.answer", answerArray);

                var instance = new JArray();
                instance.Add(JObject.FromObject(topAnswer));
                ObjectPath.SetPathValue(recognizerResult, "entities.$instance.answer", instance);

                recognizerResult.Properties["answers"] = answers;
            }
            else
            {
                recognizerResult.Intents.Add("None", new IntentScore()
                {
                    Score = 1.0f
                });
            }

            this.TelemetryClient.TrackEvent("QnAMakerRecognizerResult", this.FillRecognizerResultTelemetryProperties(recognizerResult, telemetryProperties), telemetryMetrics);

            return(recognizerResult);
        }
        private async Task <DialogTurnResult> CallGenerateAnswerAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var dialogOptions = ObjectPath.GetPathValue <QnAMakerDialogOptions>(stepContext.ActiveDialog.State, Options);

            // Resetting context and QnAId
            dialogOptions.QnAMakerOptions.QnAId   = 0;
            dialogOptions.QnAMakerOptions.Context = new QnARequestContext();

            // Storing the context info
            stepContext.Values[ValueProperty.CurrentQuery] = stepContext.Context.Activity.Text;

            // -Check if previous context is present, if yes then put it with the query
            // -Check for id if query is present in reverse index.
            var previousContextData = ObjectPath.GetPathValue <Dictionary <string, int> >(stepContext.ActiveDialog.State, QnAContextData, new Dictionary <string, int>());
            var previousQnAId       = ObjectPath.GetPathValue <int>(stepContext.ActiveDialog.State, PreviousQnAId, 0);

            if (previousQnAId > 0)
            {
                dialogOptions.QnAMakerOptions.Context = new QnARequestContext
                {
                    PreviousQnAId = previousQnAId
                };

                if (previousContextData.TryGetValue(stepContext.Context.Activity.Text, out var currentQnAId))
                {
                    dialogOptions.QnAMakerOptions.QnAId = currentQnAId;
                }
            }

            // Calling QnAMaker to get response.
            var qnaClient = await GetQnAMakerClientAsync(stepContext).ConfigureAwait(false);

            var response = await qnaClient.GetAnswersRawAsync(stepContext.Context, dialogOptions.QnAMakerOptions).ConfigureAwait(false);

            // Resetting previous query.
            previousQnAId = -1;
            ObjectPath.SetPathValue(stepContext.ActiveDialog.State, PreviousQnAId, previousQnAId);

            // Take this value from GetAnswerResponse
            var isActiveLearningEnabled = response.ActiveLearningEnabled;

            stepContext.Values[ValueProperty.QnAData] = new List <QueryResult>(response.Answers);

            // Check if active learning is enabled.
            // maximumScoreForLowScoreVariation is the score above which no need to check for feedback.
            if (isActiveLearningEnabled && response.Answers.Any() && response.Answers.First().Score <= maximumScoreForLowScoreVariation)
            {
                // Get filtered list of the response that support low score variation criteria.
                response.Answers = qnaClient.GetLowScoreVariation(response.Answers);

                if (response.Answers.Count() > 1)
                {
                    var suggestedQuestions = new List <string>();
                    foreach (var qna in response.Answers)
                    {
                        suggestedQuestions.Add(qna.Questions[0]);
                    }

                    // Get active learning suggestion card activity.
                    var message = QnACardBuilder.GetSuggestionsCard(suggestedQuestions, dialogOptions.ResponseOptions.ActiveLearningCardTitle, dialogOptions.ResponseOptions.CardNoMatchText);
                    await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);

                    ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions);
                    return(new DialogTurnResult(DialogTurnStatus.Waiting));
                }
            }

            var result = new List <QueryResult>();

            if (response.Answers.Any())
            {
                result.Add(response.Answers.First());
            }

            stepContext.Values[ValueProperty.QnAData] = result;
            ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions);

            // If card is not shown, move to next step with top QnA response.
            return(await stepContext.NextAsync(result, cancellationToken).ConfigureAwait(false));
        }
        public async override Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken = default, Dictionary <System.String, System.String> telemetryProperties = null, Dictionary <System.String, System.Double> telemetryMetrics = null)
        {
            var qluceneEngine = await QLuceneEngineCache.GetEngine(dialogContext, this.KnowledgeBase).ConfigureAwait(false);

            var threshold        = Threshold.GetValue(dialogContext);
            var recognizerResult = new RecognizerResult
            {
                Text    = activity.Text,
                Intents = new Dictionary <string, IntentScore>(),
            };

            if (string.IsNullOrEmpty(activity.Text))
            {
                recognizerResult.Intents.Add("None", new IntentScore());
                return(recognizerResult);
            }
            var  rankerType = RankerType?.GetValue(dialogContext.State);
            var  strictFiltersCompoundOperationType = StrictFiltersCompoundOperationType?.GetValue(dialogContext.State);
            var  strictFilters = new List <Metadata>();
            var  context       = Context?.GetValue(dialogContext.State);
            bool includeDialogNameInMetadata = IncludeDialogNameInMetadata.GetValue(dialogContext.State);

            if (includeDialogNameInMetadata)
            {
                strictFilters.Add(new Metadata
                {
                    Name  = "dialogName",
                    Value = dialogContext.ActiveDialog.Id
                });
            }

            // if there is $qna.metadata set add to filters
            var externalMetadata = StrictFilters?.GetValue(dialogContext.State);

            if (externalMetadata != null)
            {
                strictFilters.AddRange(externalMetadata);
            }

            var topAnswer = qluceneEngine.GetAnswers(activity.Text,
                                                     strictFilters: strictFilters.ToArray(),
                                                     context: context,
                                                     threshold: threshold,
                                                     rankerType: rankerType,
                                                     strictFiltersCompoundOperationType: strictFiltersCompoundOperationType);

            if (topAnswer != null)
            {
                if (topAnswer.Answer.Trim().ToUpperInvariant().StartsWith(IntentPrefix.ToUpperInvariant(), StringComparison.Ordinal))
                {
                    recognizerResult.Intents.Add(topAnswer.Answer.Trim().Substring(IntentPrefix.Length).Trim(), new IntentScore {
                        Score = topAnswer.Score
                    });
                }
                else
                {
                    recognizerResult.Intents.Add(QnAMatchIntent, new IntentScore {
                        Score = topAnswer.Score
                    });
                }

                var answerArray = new JArray();
                answerArray.Add(topAnswer.Answer);
                ObjectPath.SetPathValue(recognizerResult, "entities.answer", answerArray);

                var instance = new JArray();
                var data     = JObject.FromObject(topAnswer);
                data["startIndex"] = 0;
                data["endIndex"]   = activity.Text.Length;
                instance.Add(data);
                ObjectPath.SetPathValue(recognizerResult, "entities.$instance.answer", instance);

                // recognizerResult.Properties["answers"] = answers;
            }
            else
            {
                recognizerResult.Intents.Add("None", new IntentScore {
                    Score = 1.0f
                });
            }

            var traceInfo = new
            {
                recognizerResult,
                options = new
                {
                    id             = this.Id,
                    knowledgeBase  = this.KnowledgeBase,
                    scoreThreshold = threshold,
                    context,
                    rankerType,
                    strictFilters = strictFilters.ToArray(),
                    includeDialogNameInMetadata,
                    strictFiltersCompoundOperationType
                }
            };

            await dialogContext.Context.TraceActivityAsync(nameof(QLuceneRecognizer), traceInfo, TraceType, TraceLabel, cancellationToken).ConfigureAwait(false);

            return(recognizerResult);
        }
Exemple #22
0
        protected virtual async Task <Dictionary <string, JObject> > GetEntityMap(DialogContext dc)
        {
            var url = this.Url?.GetValue(dc);

            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException(nameof(this.Url));
            }

            if (!entityMaps.TryGetValue(url, out var entityMap))
            {
                IEnumerable <string> lines = Array.Empty <string>();

                if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
                {
                    Uri uri = new Uri(url);
                    if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
                    {
                        var response = await httpClient.GetAsync(url);

                        var text = await response.Content.ReadAsStringAsync();

                        using (var reader = new System.IO.StringReader(text))
                        {
                            var    lineList = new List <string>();
                            string line;
                            while ((line = reader.ReadLine()) != null)
                            {
                                lineList.Add(line);
                            }
                            lines = lineList;
                        }
                    }
                    else
                    {
                        throw new Exception("Bad Uri");
                    }
                }
                else
                {
                    var path = url
                               .Replace('/', Path.DirectorySeparatorChar)
                               .Replace('\\', Path.DirectorySeparatorChar);
                    lines = File.ReadAllLines(path);
                }

                var firstLine = lines.First();
                var columns   = firstLine.Split(',').Select(t => t.Trim()).ToArray();

                entityMap = new Dictionary <string, JObject>();
                foreach (var line in lines.Skip(1))
                {
                    var values = line.Split(',');

                    dynamic payload = new JObject();
                    string  token   = null;
                    for (int col = 0; col < columns.Length; col++)
                    {
                        string colName = columns[col];
                        if (colName == "token")
                        {
                            token = values[col].Trim();
                        }
                        else
                        {
                            if (int.TryParse(values[col], out int intValue))
                            {
                                ObjectPath.SetPathValue(payload, colName, intValue);
                            }
                            else if (float.TryParse(values[col], out float floatValue))
                            {
                                ObjectPath.SetPathValue(payload, colName, floatValue);
                            }
                            else
                            {
                                ObjectPath.SetPathValue(payload, colName, values[col].Trim());
                            }
                        }
                    }

                    entityMap[token] = payload;
                }

                entityMaps[url] = entityMap;
            }

            return(entityMap);
        }
Exemple #23
0
        public override async Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, string text, string locale, CancellationToken cancellationToken)
        {
            var dcState = dialogContext.GetState();

            // Identify matched intents
            var utterance = text ?? string.Empty;

            var recognizerResult = new RecognizerResult()
            {
                Text    = utterance,
                Intents = new Dictionary <string, IntentScore>(),
            };

            List <Metadata> filters = new List <Metadata>()
            {
                new Metadata()
                {
                    Name = "dialogName", Value = dialogContext.ActiveDialog.Id
                }
            };

            // if there is $qna.metadata set add to filters
            var externalMetadata = dcState.GetValue <Metadata[]>("$qna.metadata");

            if (externalMetadata != null)
            {
                filters.AddRange(externalMetadata);
            }

            // Calling QnAMaker to get response.
            var qnaClient = await GetQnAMakerClientAsync(dialogContext).ConfigureAwait(false);

            var answers = await qnaClient.GetAnswersAsync(
                dialogContext.Context,
                new QnAMakerOptions
            {
                Context        = dcState.GetValue <QnARequestContext>("$qna.context"),
                ScoreThreshold = this.Threshold.TryGetValue(dcState).Value,
                StrictFilters  = filters.ToArray(),
                Top            = this.Top.TryGetValue(dcState).Value,
                QnAId          = 0,
                RankerType     = this.RankerType.TryGetValue(dcState).Value,
                IsTest         = this.IsTest
            },
                null).ConfigureAwait(false);

            if (answers.Any())
            {
                QueryResult topAnswer = null;
                foreach (var answer in answers)
                {
                    if ((topAnswer == null) || (answer.Score > topAnswer.Score))
                    {
                        topAnswer = answer;
                    }
                }

                if (topAnswer.Answer.Trim().ToLower().StartsWith(IntentPrefix))
                {
                    recognizerResult.Intents.Add(topAnswer.Answer.Trim().Substring(IntentPrefix.Length).Trim(), new IntentScore()
                    {
                        Score = topAnswer.Score
                    });
                }
                else
                {
                    recognizerResult.Intents.Add(QnAMatchIntent, new IntentScore()
                    {
                        Score = topAnswer.Score
                    });
                }

                var answerArray = new JArray();
                answerArray.Add(topAnswer.Answer);
                ObjectPath.SetPathValue(recognizerResult, "entities.answer", answerArray);

                var instance = new JArray();
                instance.Add(JObject.FromObject(topAnswer));
                ObjectPath.SetPathValue(recognizerResult, "entities.$instance.answer", instance);

                recognizerResult.Properties["answers"] = answers;
            }
            else
            {
                recognizerResult.Intents.Add("None", new IntentScore()
                {
                    Score = 1.0f
                });
            }

            return(recognizerResult);
        }
Exemple #24
0
        private async Task <DialogTurnResult> CallGenerateAnswerAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            // clear suggestedQuestions between turns.
            stepContext.State.RemoveValue($"this.suggestedQuestions");

            var dialogOptions = ObjectPath.GetPathValue <QnAMakerDialogOptions>(stepContext.ActiveDialog.State, Options);

            ResetOptions(stepContext, dialogOptions);

            // Storing the context info
            stepContext.Values[ValueProperty.CurrentQuery] = stepContext.Context.Activity.Text;

            // Calling QnAMaker to get response.
            var qnaClient = await GetQnAMakerClientAsync(stepContext).ConfigureAwait(false);

            var response = stepContext.State.GetValue <QueryResults>($"turn.qnaresult{this.GetHashCode()}");

            if (response == null)
            {
                response = await qnaClient.GetAnswersRawAsync(stepContext.Context, dialogOptions.QnAMakerOptions).ConfigureAwait(false);
            }

            // Resetting previous query.
            var previousQnAId = -1;

            ObjectPath.SetPathValue(stepContext.ActiveDialog.State, PreviousQnAId, previousQnAId);

            // Take this value from GetAnswerResponse
            var isActiveLearningEnabled = response.ActiveLearningEnabled;

            stepContext.Values[ValueProperty.QnAData] = new List <QueryResult>(response.Answers);

            // Check if active learning is enabled.
            // MaximumScoreForLowScoreVariation is the score above which no need to check for feedback.
            if (response.Answers.Any() && response.Answers.First().Score <= (ActiveLearningUtils.MaximumScoreForLowScoreVariation / 100))
            {
                // Get filtered list of the response that support low score variation criteria.
                response.Answers = qnaClient.GetLowScoreVariation(response.Answers);

                if (response.Answers.Length > 1 && isActiveLearningEnabled)
                {
                    var suggestedQuestions = new List <string>();
                    foreach (var qna in response.Answers)
                    {
                        suggestedQuestions.Add(qna.Questions[0]);
                    }

                    // Get active learning suggestion card activity.
                    var message = QnACardBuilder.GetSuggestionsCard(suggestedQuestions, dialogOptions.ResponseOptions.ActiveLearningCardTitle, dialogOptions.ResponseOptions.CardNoMatchText);
                    await stepContext.Context.SendActivityAsync(message).ConfigureAwait(false);

                    ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions);
                    stepContext.State.SetValue($"this.suggestedQuestions", suggestedQuestions);
                    return(new DialogTurnResult(DialogTurnStatus.Waiting));
                }
            }

            var result = new List <QueryResult>();

            if (response.Answers.Any())
            {
                result.Add(response.Answers.First());
            }

            stepContext.Values[ValueProperty.QnAData] = result;
            ObjectPath.SetPathValue(stepContext.ActiveDialog.State, Options, dialogOptions);

            // If card is not shown, move to next step with top QnA response.
            return(await stepContext.NextAsync(result, cancellationToken).ConfigureAwait(false));
        }
        public override async Task <DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default)
        {
            if (options is CancellationToken)
            {
                throw new ArgumentException($"{nameof(options)} should not ever be a cancellation token");
            }

            EnsureDependenciesInstalled();

            await this.CheckForVersionChangeAsync(dc, cancellationToken).ConfigureAwait(false);

            var cardId = CardId?.GetValue(dc.State);

            var activeDialogState = dc.ActiveDialog.State as Dictionary <string, object>;

            activeDialogState[AdaptiveKey] = new AdaptiveDialogState();

            var properties = new Dictionary <string, string>()
            {
                { "DialogId", Id },
                { "Kind", Kind }
            };

            TelemetryClient.TrackEvent("AdaptiveCardDialogStart", properties);

            // select trigger
            if (!dc.State.TryGetValue <DialogEvent>("turn.dialogEvent", out DialogEvent dialogEvent))
            {
                dialogEvent = new DialogEvent {
                    Name = AdaptiveEvents.ActivityReceived, Value = dc.Context.Activity, Bubble = false
                };
                // If AdaptiveCardDialog is root dialog there may not be a dialogEvent, and conditions are
                // looking for this dialogevent as a condition.
                dc.State.SetValue("turn.dialogEvent", dialogEvent);
            }

            var actionContext = ToActionContext(dc);
            var selection     = await this.selector.SelectAsync(actionContext, cancellationToken).ConfigureAwait(false);

            if (selection.Any())
            {
                var condition = selection[0];

                await actionContext.DebuggerStepAsync(condition, dialogEvent, cancellationToken).ConfigureAwait(false);

                System.Diagnostics.Trace.TraceInformation($"Executing AdaptiveCardDialog: {Id} Rule[{condition.Id}]: {condition.GetType().Name}: {condition.GetExpression()}");

                var changes = await condition.ExecuteAsync(actionContext);

                if (changes != null && changes.Any())
                {
                    actionContext.QueueChanges(changes[0]);
                    await actionContext.ApplyChangesAsync(cancellationToken).ConfigureAwait(false);

                    var actionDC = CreateChildContext(actionContext);

                    // execute the sequence, the action should be an actionScope, so we simply start the actionAcope from the selected changelist.
                    // NOTE: We don't do any of the changelist dialog management stuff because we are always single turn response with no dialog stack.
                    var result = await actionDC.BeginDialogAsync(changes[0].Actions[0].DialogId);

                    if (result.Status == DialogTurnStatus.Waiting)
                    {
                        throw new NotSupportedException("You can't wait in an invoke activity");
                    }
                }
            }

            // --- data bind the template ----
            if (this.Template == null)
            {
                throw new Exception($"{this.Id}: a template was not provided or is not valid JSON.");
            }

            // Get data
            var data = this.Data?.GetValue(dc.State);

            if (data == null)
            {
                // template library barfs on dialogclass and class memory scopes because it tries to serialize them.
                data = dc.State.Where(kv => kv.Key != "dialogclass" && kv.Key != "class").ToDictionary(kv => kv.Key, kv2 => kv2.Value);
            }

            // bind the card and convert to JObject
            var cardJson = this.Template.Expand(data);
            var card     = !String.IsNullOrEmpty(cardJson) ? JObject.Parse(cardJson) : null;

            // stamp dialogId and cardId on all Action.Execute nodes.
            // set data.cardId = cardId on Action.Execute Nodes
            foreach (var action in card.SelectTokens("$..[?(@.type=='Action.Execute')]").OfType <JObject>())
            {
                ObjectPath.SetPathValue(action, "data.dialogId", this.Id);
                ObjectPath.SetPathValue(action, "data.cardId", cardId);
            }

            // Send invoke response (new card)
            var response = new JObject()
            {
                { "statusCode", 200 },
                { "type", AdaptiveCard.ContentType },
                { "value", card }
            };
            var activity = new Activity(type: ActivityTypesEx.InvokeResponse, value: new InvokeResponse()
            {
                Status = 200, Body = response
            });
            await dc.Context.SendActivityAsync(activity, cancellationToken).ConfigureAwait(false);

            return(await dc.EndDialogAsync(null, cancellationToken).ConfigureAwait(false));
        }