/// <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)); }
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()); }
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); }
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 }
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); }
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); }
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); }
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)); }