public ModelHelpers(IBackend gallifrey, FlyoutsControl flyoutsControl) { this.flyoutsControl = flyoutsControl; Gallifrey = gallifrey; DialogContext = new DialogContext(); openFlyouts = new List<OpenFlyoutDetails>(); }
protected override async Task RouteAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { var state = await _conversationStateAccessor.GetAsync(dc.Context, () => new SkillConversationState()); // get current activity locale var locale = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; var localeConfig = _services.LocaleConfigurations[locale]; // Get skill LUIS model from configuration localeConfig.LuisServices.TryGetValue("FakeSkill", out var luisService); if (luisService == null) { throw new Exception("The specified LUIS Model could not be found in your Bot Services configuration."); } else { var skillOptions = new SkillTemplateDialogOptions { SkillMode = _skillMode, }; var result = await luisService.RecognizeAsync <FakeSkillLU>(dc.Context, CancellationToken.None); var intent = result?.TopIntent().intent; switch (intent) { case FakeSkillLU.Intent.Sample: { await dc.BeginDialogAsync(nameof(SampleDialog), skillOptions); break; } case FakeSkillLU.Intent.Auth: { await dc.BeginDialogAsync(nameof(AuthDialog), skillOptions); break; } case FakeSkillLU.Intent.None: { // No intent was identified, send confused message await dc.Context.SendActivityAsync(_responseManager.GetResponse(SharedResponses.DidntUnderstandMessage)); if (_skillMode) { await CompleteAsync(dc); } break; } default: { // intent was identified but not yet implemented await dc.Context.SendActivityAsync(_responseManager.GetResponse(MainResponses.FeatureNotAvailable)); if (_skillMode) { await CompleteAsync(dc); } break; } } } }
public override async Task <DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { // We're being continued after an interruption so just run next action return(await OnNextActionAsync(dc, null, cancellationToken).ConfigureAwait(false)); }
public override Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, CancellationToken cancellationToken = default) { return(this.RecognizeAsync(dialogContext.Context, cancellationToken)); }
protected virtual object OnInitializeOptions(DialogContext dc, object options) { return(options); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { return(await this.PromptUser(dc, InputState.Missing).ConfigureAwait(false)); }
protected async override Task <DialogTurnResult> OnBeginDialogAsync(DialogContext innerDc, object options, CancellationToken cancellationToken = default(CancellationToken)) { // Override default begin() logic with interruption orchestration logic return(await InterruptionDispatchAsync(innerDc, options)); }
/// <summary> /// Deletes any state in storage and the cache for this <see cref="BotState"/>. /// </summary> /// <param name="dialogContext">The dialog context object for this turn.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A task that represents the work queued to execute.</returns> /// <exception cref="ArgumentNullException"><paramref name="turnContext"/> is <c>null</c>.</exception> public virtual Task DeleteAsync(DialogContext dialogContext, CancellationToken cancellationToken = default(CancellationToken)) { return(Task.CompletedTask); }
protected async Task DigestCalendarLuisResult(DialogContext dc, Calendar luisResult, bool isBeginDialog) { try { var state = await Accessor.GetAsync(dc.Context); var intent = luisResult.TopIntent().intent; var entity = luisResult.Entities; if (entity.ordinal != null) { try { var eventList = state.SummaryEvents; var value = entity.ordinal[0]; var num = int.Parse(value.ToString()); if (eventList != null && num > 0) { var currentList = eventList.GetRange(0, Math.Min(CalendarSkillState.PageSize, eventList.Count)); if (num <= currentList.Count) { state.ReadOutEvents.Clear(); state.ReadOutEvents.Add(currentList[num - 1]); } } } catch { // ignored } } if (entity.number != null && entity.ordinal != null && entity.ordinal.Length == 0) { try { var eventList = state.SummaryEvents; var value = entity.ordinal[0]; var num = int.Parse(value.ToString()); if (eventList != null && num > 0) { var currentList = eventList.GetRange(0, Math.Min(CalendarSkillState.PageSize, eventList.Count)); if (num <= currentList.Count) { state.ReadOutEvents.Clear(); state.ReadOutEvents.Add(currentList[num - 1]); } } } catch { // ignored } } if (!isBeginDialog) { return; } switch (intent) { case Calendar.Intent.FindMeetingRoom: case Calendar.Intent.CreateCalendarEntry: { if (entity.Subject != null) { state.Title = GetSubjectFromEntity(entity); } if (entity.ContactName != null) { state.AttendeesNameList = GetAttendeesFromEntity(entity, luisResult.Text, state.AttendeesNameList); } if (entity.FromDate != null) { var date = GetDateFromDateTimeString(entity.FromDate[0], dc.Context.Activity.Locale, state.GetUserTimeZone()); if (date != null) { state.StartDate = date; } } if (entity.ToDate != null) { var date = GetDateFromDateTimeString(entity.ToDate[0], dc.Context.Activity.Locale, state.GetUserTimeZone()); if (date != null) { state.EndDate = date; } } if (entity.FromTime != null) { var time = GetTimeFromDateTimeString(entity.FromTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone(), true); if (time != null) { state.StartTime = time; } time = GetTimeFromDateTimeString(entity.FromTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone(), false); if (time != null) { state.EndTime = time; } } if (entity.ToTime != null) { var time = GetTimeFromDateTimeString(entity.ToTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone()); if (time != null) { state.EndTime = time; } } if (entity.Duration != null) { int duration = GetDurationFromEntity(entity, dc.Context.Activity.Locale); if (duration != -1) { state.Duration = duration; } } if (entity.MeetingRoom != null) { state.Location = GetMeetingRoomFromEntity(entity); } if (entity.Location != null) { state.Location = GetLocationFromEntity(entity); } break; } case Calendar.Intent.DeleteCalendarEntry: { if (entity.Subject != null) { state.Title = GetSubjectFromEntity(entity); } if (entity.FromDate != null) { var date = GetDateFromDateTimeString(entity.FromDate[0], dc.Context.Activity.Locale, state.GetUserTimeZone()); if (date != null) { state.StartDate = date; } } if (entity.FromTime != null) { var time = GetTimeFromDateTimeString(entity.FromTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone(), true); if (time != null) { state.StartTime = time; } } break; } case Calendar.Intent.NextMeeting: { break; } case Calendar.Intent.ChangeCalendarEntry: { if (entity.Subject != null) { state.Title = GetSubjectFromEntity(entity); } if (entity.FromDate != null) { var date = GetDateFromDateTimeString(entity.FromDate[0], dc.Context.Activity.Locale, state.GetUserTimeZone()); if (date != null) { state.OriginalStartDate = date; } } if (entity.ToDate != null) { var date = GetDateFromDateTimeString(entity.ToDate[0], dc.Context.Activity.Locale, state.GetUserTimeZone()); if (date != null) { state.StartDate = date; } } if (entity.FromTime != null) { var time = GetTimeFromDateTimeString(entity.FromTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone(), true); if (time != null) { state.OriginalStartTime = time; } time = GetTimeFromDateTimeString(entity.FromTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone(), false); if (time != null) { state.OriginalEndTime = time; } } if (entity.ToTime != null) { var time = GetTimeFromDateTimeString(entity.ToTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone(), true); if (time != null) { state.StartTime = time; } time = GetTimeFromDateTimeString(entity.ToTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone(), false); if (time != null) { state.EndTime = time; } } if (entity.MoveEarlierTimeSpan != null) { state.MoveTimeSpan = GetMoveTimeSpanFromEntity(entity.MoveEarlierTimeSpan[0], dc.Context.Activity.Locale, false); } if (entity.MoveLaterTimeSpan != null) { state.MoveTimeSpan = GetMoveTimeSpanFromEntity(entity.MoveLaterTimeSpan[0], dc.Context.Activity.Locale, true); } break; } case Calendar.Intent.FindCalendarEntry: case Calendar.Intent.Summary: { if (entity.FromDate != null) { var date = GetDateFromDateTimeString(entity.FromDate[0], dc.Context.Activity.Locale, state.GetUserTimeZone()); if (date != null) { state.StartDate = date; } } if (entity.ToDate != null) { var date = GetDateFromDateTimeString(entity.ToDate[0], dc.Context.Activity.Locale, state.GetUserTimeZone()); if (date != null) { state.EndDate = date; } } if (entity.FromTime != null) { var time = GetTimeFromDateTimeString(entity.FromTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone(), true); if (time != null) { state.StartTime = time; } time = GetTimeFromDateTimeString(entity.FromTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone(), false); if (time != null) { state.EndTime = time; } } if (entity.ToTime != null) { var time = GetTimeFromDateTimeString(entity.ToTime[0], dc.Context.Activity.Locale, state.GetUserTimeZone()); if (time != null) { state.EndTime = time; } } break; } case Calendar.Intent.None: { break; } default: { break; } } } catch { var state = await Accessor.GetAsync(dc.Context); state.Clear(); await dc.CancelAllDialogsAsync(); throw; } }
protected abstract Task <InterruptionStatus> OnDialogInterruptionAsync(DialogContext dc, CancellationToken cancellationToken);
public override void SetMemory(DialogContext dc, object memory) { throw new NotSupportedException("You cannot set the memory for a readonly memory scope"); }
private async Task RecognizeEntitiesAsync(DialogContext dialogContext, Schema.Activity activity, RecognizerResult recognizerResult) { var text = activity.Text ?? string.Empty; var entityPool = new List <Entity>(); if (EntityRecognizers != null) { // add entities from regexrecgonizer to the entities pool var textEntity = new TextEntity(text); textEntity.Properties["start"] = 0; textEntity.Properties["end"] = text.Length; textEntity.Properties["score"] = 1.0; entityPool.Add(textEntity); // process entities using EntityRecognizerSet var entitySet = new EntityRecognizerSet(EntityRecognizers); var newEntities = await entitySet.RecognizeEntitiesAsync(dialogContext, activity, entityPool).ConfigureAwait(false); if (newEntities.Any()) { entityPool.AddRange(newEntities); } entityPool.Remove(textEntity); } // map entityPool of Entity objects => RecognizerResult entity format recognizerResult.Entities = new JObject(); foreach (var entityResult in entityPool) { // add value JToken values; if (!recognizerResult.Entities.TryGetValue(entityResult.Type, StringComparison.OrdinalIgnoreCase, out values)) { values = new JArray(); recognizerResult.Entities[entityResult.Type] = values; } // The Entity type names are not consistent, map everything to camelcase so we can process them cleaner. var entity = JObject.FromObject(entityResult); ((JArray)values).Add(entity.GetValue("text", StringComparison.InvariantCulture)); // get/create $instance if (!recognizerResult.Entities.TryGetValue("$instance", StringComparison.OrdinalIgnoreCase, out JToken instanceRoot)) { instanceRoot = new JObject(); recognizerResult.Entities["$instance"] = instanceRoot; } // add instanceData if (!((JObject)instanceRoot).TryGetValue(entityResult.Type, StringComparison.OrdinalIgnoreCase, out JToken instanceData)) { instanceData = new JArray(); instanceRoot[entityResult.Type] = instanceData; } var instance = new JObject(); instance.Add("startIndex", entity.GetValue("start", StringComparison.InvariantCulture)); instance.Add("endIndex", entity.GetValue("end", StringComparison.InvariantCulture)); instance.Add("score", (double)1.0); instance.Add("text", entity.GetValue("text", StringComparison.InvariantCulture)); instance.Add("type", entity.GetValue("type", StringComparison.InvariantCulture)); instance.Add("resolution", entity.GetValue("resolution", StringComparison.InvariantCulture)); ((JArray)instanceData).Add(instance); } }
/// <summary> /// Return recognition results. /// </summary> /// <param name="dc">Context object containing information for a single turn of conversation with a user.</param> /// <param name="activity">The incoming activity received from the user. The Text property value is used as the query text for QnA Maker.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <param name="telemetryProperties">Additional properties to be logged to telemetry with the LuisResult event.</param> /// <param name="telemetryMetrics">Additional metrics to be logged to telemetry with the LuisResult event.</param> /// <returns>A <see cref="RecognizerResult"/> containing the QnA Maker result.</returns> public override async Task <RecognizerResult> RecognizeAsync(DialogContext dc, Schema.Activity activity, CancellationToken cancellationToken, Dictionary <string, string> telemetryProperties = null, Dictionary <string, double> telemetryMetrics = null) { var text = activity.Text ?? string.Empty; var detectAmbiguity = DetectAmbiguousIntents.GetValue(dc.State); _modelPath = ModelPath.GetValue(dc.State); _snapshotPath = SnapshotPath.GetValue(dc.State); InitializeModel(); var recognizerResult = new RecognizerResult() { Text = text, Intents = new Dictionary <string, IntentScore>(), }; if (string.IsNullOrWhiteSpace(text)) { // nothing to recognize, return empty recognizerResult return(recognizerResult); } if (EntityRecognizers.Count != 0) { // Run entity recognition await RecognizeEntitiesAsync(dc, activity, recognizerResult).ConfigureAwait(false); } // Score with orchestrator var results = _resolver.Score(text); // Add full recognition result as a 'result' property recognizerResult.Properties.Add(ResultProperty, results); if (results.Any()) { var topScore = results[0].Score; // if top scoring intent is less than threshold, return None if (topScore < UnknownIntentFilterScore) { recognizerResult.Intents.Add(NoneIntent, new IntentScore() { Score = 1.0 }); } else { // add top score recognizerResult.Intents.Add(results[0].Label.Name, new IntentScore() { Score = results[0].Score }); // Disambiguate if configured if (detectAmbiguity) { var thresholdScore = DisambiguationScoreThreshold.GetValue(dc.State); var classifyingScore = Math.Round(topScore, 2) - Math.Round(thresholdScore, 2); var ambiguousResults = results.Where(item => item.Score >= classifyingScore).ToList(); if (ambiguousResults.Count > 1) { // create a RecognizerResult for each ambiguous result. var recognizerResults = ambiguousResults.Select(result => new RecognizerResult() { Text = text, AlteredText = result.ClosestText, Entities = recognizerResult.Entities, Properties = recognizerResult.Properties, Intents = new Dictionary <string, IntentScore>() { { result.Label.Name, new IntentScore() { Score = result.Score } } }, }); // replace RecognizerResult with ChooseIntent => Ambiguous recognizerResults as candidates. recognizerResult = CreateChooseIntentResult(recognizerResults.ToDictionary(result => Guid.NewGuid().ToString(), result => result)); } } } } else { // Return 'None' if no intent matched. recognizerResult.Intents.Add(NoneIntent, new IntentScore() { Score = 1.0 }); } await dc.Context.TraceActivityAsync(nameof(OrchestratorAdaptiveRecognizer), JObject.FromObject(recognizerResult), nameof(OrchestratorAdaptiveRecognizer), "Orchestrator Recognition ", cancellationToken).ConfigureAwait(false); TrackRecognizerResult(dc, nameof(OrchestratorAdaptiveRecognizer), FillRecognizerResultTelemetryProperties(recognizerResult, telemetryProperties), telemetryMetrics); return(recognizerResult); }
public async Task <DialogTurnResult> Handle(DialogContext dialogContext, CancellationToken cancellationToken) { //dialogContext.Dialogs.Add(dia); return(await dialogContext.BeginDialogAsync(_whoIsSHeDialog.Id, cancellationToken : cancellationToken)); }
public override Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { return(null); }
/// <summary> /// Writes the state cache for this <see cref="BotState"/> to the storage layer. /// </summary> /// <param name="dialogContext">The dialog context object for this turn.</param> /// <param name="force">Optional, <c>true</c> to save the state cache to storage; /// or <c>false</c> to save state to storage only if a property in the cache has changed.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A task that represents the work queued to execute.</returns> /// <exception cref="ArgumentNullException"><paramref name="turnContext"/> is <c>null</c>.</exception> public virtual Task SaveChangesAsync(DialogContext dialogContext, bool force = false, CancellationToken cancellationToken = default(CancellationToken)) { return(Task.CompletedTask); }
// Helpers public async Task DigestLuisResult(DialogContext dc, weather luisResult) { try { var state = await Accessor.GetAsync(dc.Context); // extract entities and store in state here. if (luisResult.Entities.Weather_Location != null && luisResult.Entities.Weather_Location.Length > 0) { state.Locations.Clear(); foreach (var location in luisResult.Entities.Weather_Location) { if (!state.Locations.Contains(location)) { state.Locations.Add(location); } } } if (luisResult.Entities.datetime != null && luisResult.Entities.datetime.Length > 0) { state.ForecastTimes.Clear(); foreach (var datespcs in luisResult.Entities.datetime) { switch (datespcs.Type) { case "date": if (datespcs.Expressions.Count > 0) { var forecast = new ForecastTime { StartTime = null, Type = ForecastType.Day }; if (DateTime.TryParse(datespcs.Expressions[0], out DateTime time)) { forecast.StartTime = time; } state.ForecastTimes.Add(forecast); } break; case "datetime": if (datespcs.Expressions.Count > 0) { var forecast = new ForecastTime { StartTime = null, Type = ForecastType.Hour }; if (DateTime.TryParse(datespcs.Expressions[0], out DateTime time)) { forecast.StartTime = time; } state.ForecastTimes.Add(forecast); } break; } } } if (luisResult.Entities.Wear_Clothes != null && luisResult.Entities.Wear_Clothes.Length > 0) { state.Clothes.Clear(); foreach (var cloth in luisResult.Entities.Wear_Clothes) { if (!state.Clothes.Contains(cloth)) { state.Clothes.Add(cloth); } } } } catch { // put log here } }
public override void SetMemory(DialogContext dc, object memory) { throw new NotSupportedException("You can't modify the class scope"); }
private static async Task Waterfall3_Step2(DialogContext dc, object args, SkipStepFunction next) { await dc.Context.SendActivity("step2"); await dc.Begin("test-waterfall-c"); }
protected async override Task <DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default(CancellationToken)) { // Override default continue() logic with interruption orchestration logic return(await InterruptionDispatchAsync(innerDc, null)); }
private static async Task Waterfall4_Step1(DialogContext dc, object args, SkipStepFunction next) { await dc.Context.SendActivity("step1.1"); }
protected abstract Task <InputState> OnRecognizeInput(DialogContext dc);
private static async Task Waterfall5_Step2(DialogContext dc, object args, SkipStepFunction next) { await dc.Context.SendActivity("step2.2"); await dc.End(); }
private async Task <InputState> RecognizeInput(DialogContext dc, int turnCount) { dynamic input = null; // Use Property expression for input first if (!string.IsNullOrEmpty(this.Property)) { dc.State.TryGetValue(this.Property, out input); // Clear property to avoid it being stuck on the next turn. It will get written // back if the value passes validations. dc.State.SetValue(this.Property, null); } // Use Value expression for input second if (input == null && !string.IsNullOrEmpty(this.Value)) { dc.State.TryGetValue(this.Value, out input); } // Fallback to using activity if (input == null && turnCount > 0) { if (this.GetType().Name == nameof(AttachmentInput)) { input = dc.Context.Activity.Attachments; } else { input = dc.Context.Activity.Text; } } // Update "this.value" and perform additional recognition and validations dc.State.SetValue(VALUE_PROPERTY, input); if (input != null) { var state = await this.OnRecognizeInput(dc).ConfigureAwait(false); if (state == InputState.Valid) { foreach (var validation in this.Validations) { var exp = new ExpressionEngine().Parse(validation); var(value, error) = exp.TryEvaluate(dc.State); if (value == null || (value is bool && (bool)value == false)) { return(InputState.Invalid); } } return(InputState.Valid); } else { return(state); } } else { return(InputState.Missing); } }
private static async Task Waterfall2_Step1(DialogContext dc, object args, SkipStepFunction next) { await dc.Context.SendActivity("step1"); await dc.Prompt("number", "Enter a number.", new PromptOptions { RetryPromptString = "It must be a number" }); }
protected virtual async Task <DialogTurnResult> OnContinueLoopAsync(DialogContext dc, ActionScopeResult actionScopeResult, CancellationToken cancellationToken = default) { // default is to simply end the dialog and propagate to parent to handle return(await dc.EndDialogAsync(actionScopeResult, cancellationToken).ConfigureAwait(false)); }
private async Task <bool> InterruptDialogAsync(DialogContext innerDc, CancellationToken cancellationToken) { var interrupted = false; var activity = innerDc.Context.Activity; var userProfile = await _userProfileState.GetAsync(innerDc.Context, () => new UserProfileState(), cancellationToken); var dialog = innerDc.ActiveDialog?.Id != null?innerDc.FindDialog(innerDc.ActiveDialog?.Id) : null; if (activity.Type == ActivityTypes.Message && !string.IsNullOrEmpty(activity.Text)) { // Check if the active dialog is a skill for conditional interruption. var isSkill = dialog is SkillDialog; // Get Dispatch LUIS result from turn state. var dispatchResult = innerDc.Context.TurnState.Get <DispatchLuis>(StateProperties.DispatchResult); (var dispatchIntent, var dispatchScore) = dispatchResult.TopIntent(); // Check if we need to switch skills. if (isSkill && IsSkillIntent(dispatchIntent) && dispatchIntent.ToString() != dialog.Id && dispatchScore > 0.9) { if (_skillsConfig.Skills.TryGetValue(dispatchIntent.ToString(), out var identifiedSkill)) { var prompt = _templateManager.GenerateActivityForLocale("SkillSwitchPrompt", new { Skill = identifiedSkill.Name }); await innerDc.BeginDialogAsync(_switchSkillDialog.Id, new SwitchSkillDialogOptions(prompt, identifiedSkill), cancellationToken); interrupted = true; } else { throw new ArgumentException($"{dispatchIntent.ToString()} is not in the skills configuration"); } } if (dispatchIntent == DispatchLuis.Intent.l_General) { // Get connected LUIS result from turn state. var generalResult = innerDc.Context.TurnState.Get <GeneralLuis>(StateProperties.GeneralResult); (var generalIntent, var generalScore) = generalResult.TopIntent(); if (generalScore > 0.5) { switch (generalIntent) { case GeneralLuis.Intent.Cancel: { await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale("CancelledMessage", userProfile), cancellationToken); await innerDc.CancelAllDialogsAsync(cancellationToken); await innerDc.BeginDialogAsync(InitialDialogId, cancellationToken : cancellationToken); interrupted = true; break; } case GeneralLuis.Intent.Escalate: { await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale("EscalateMessage", userProfile), cancellationToken); await innerDc.RepromptDialogAsync(cancellationToken); interrupted = true; break; } case GeneralLuis.Intent.Help: { if (!isSkill) { // If current dialog is a skill, allow it to handle its own help intent. await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale("HelpCard", userProfile), cancellationToken); await innerDc.RepromptDialogAsync(cancellationToken); interrupted = true; } break; } case GeneralLuis.Intent.Logout: { // Log user out of all accounts. await LogUserOutAsync(innerDc, cancellationToken); await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale("LogoutMessage", userProfile), cancellationToken); await innerDc.CancelAllDialogsAsync(cancellationToken); await innerDc.BeginDialogAsync(InitialDialogId, cancellationToken : cancellationToken); interrupted = true; break; } case GeneralLuis.Intent.Repeat: { // Sends the activities since the last user message again. var previousResponse = await _previousResponseAccessor.GetAsync(innerDc.Context, () => new List <Activity>(), cancellationToken); foreach (var response in previousResponse) { // Reset id of original activity so it can be processed by the channel. response.Id = string.Empty; await innerDc.Context.SendActivityAsync(response, cancellationToken); } interrupted = true; break; } case GeneralLuis.Intent.StartOver: { await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale("StartOverMessage", userProfile), cancellationToken); // Cancel all dialogs on the stack. await innerDc.CancelAllDialogsAsync(cancellationToken); await innerDc.BeginDialogAsync(InitialDialogId, cancellationToken : cancellationToken); interrupted = true; break; } case GeneralLuis.Intent.Stop: { // Use this intent to send an event to your device that can turn off the microphone in speech scenarios. break; } } } } } return(interrupted); }
private async Task <InterruptionAction> OnHelp(DialogContext dc) { await dc.Context.SendActivityAsync(_responseManager.GetResponse(MainResponses.HelpMessage)); return(InterruptionAction.MessageSentToUser); }
/// <summary> /// Get the backing memory for this scope. /// </summary> /// <param name="dc">dc.</param> /// <returns>memory for the scope.</returns> public abstract object GetMemory(DialogContext dc);
/// <summary> /// Changes the backing object for the memory scope. /// </summary> /// <param name="dc">dc.</param> /// <param name="memory">memory.</param> public abstract void SetMemory(DialogContext dc, object memory);
#pragma warning restore CA2227 // Collection properties should be read only /// <summary> /// Runs current DialogContext.TurnContext.Activity through a recognizer and returns a <see cref="RecognizerResult"/>. /// </summary> /// <param name="dialogContext">The <see cref="DialogContext"/> for the current turn of conversation.</param> /// <param name="activity"><see cref="Activity"/> to recognize.</param> /// <param name="cancellationToken">Optional, <see cref="CancellationToken"/> of the task.</param> /// <param name="telemetryProperties">Optional, additional properties to be logged to telemetry with the LuisResult event.</param> /// <param name="telemetryMetrics">Optional, additional metrics to be logged to telemetry with the LuisResult event.</param> /// <returns>Analysis of utterance.</returns> public override async Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken, Dictionary <string, string> telemetryProperties = null, Dictionary <string, double> telemetryMetrics = null) { // Identify matched intents var text = activity.Text ?? string.Empty; var locale = activity.Locale ?? "en-us"; var recognizerResult = new RecognizerResult() { Text = text, }; if (string.IsNullOrWhiteSpace(text)) { // nothing to recognize, return empty recognizerResult return(recognizerResult); } // add entities from regexrecgonizer to the entities pool var entityPool = new List <Entity>(); var textEntity = new TextEntity(text); textEntity.Properties["start"] = 0; textEntity.Properties["end"] = text.Length; textEntity.Properties["score"] = 1.0; entityPool.Add(textEntity); foreach (var intentPattern in this.Intents) { var matches = intentPattern.Regex.Matches(text); if (matches.Count > 0) { // TODO length weighted match and multiple intents var intentKey = intentPattern.Intent.Replace(" ", "_"); if (!recognizerResult.Intents.ContainsKey(intentKey)) { recognizerResult.Intents.Add(intentKey, new IntentScore() { Score = 1.0, Properties = new Dictionary <string, object>() { { "pattern", intentPattern.Pattern } } }); } // Check for named capture groups // only if we have a value and the name is not a number "0" foreach (var groupName in intentPattern.Regex.GetGroupNames().Where(name => name.Length > 1)) { foreach (var match in matches.Cast <Match>()) { var group = (Group)match.Groups[groupName]; if (group.Success) { // add as entity to entity pool Entity entity = new Entity(groupName); entity.Properties["text"] = group.Value; entity.Properties["start"] = group.Index; entity.Properties["end"] = group.Index + group.Length; entityPool.Add(entity); } } } // found break; } } if (this.Entities != null) { // process entities using EntityRecognizerSet var entitySet = new EntityRecognizerSet(this.Entities); var newEntities = await entitySet.RecognizeEntitiesAsync(dialogContext, text, locale, entityPool).ConfigureAwait(false); if (newEntities.Any()) { entityPool.AddRange(newEntities); } } // map entityPool of Entity objects => RecognizerResult entity format recognizerResult.Entities = new JObject(); foreach (var entityResult in entityPool) { // add value JToken values; if (!recognizerResult.Entities.TryGetValue(entityResult.Type, StringComparison.OrdinalIgnoreCase, out values)) { values = new JArray(); recognizerResult.Entities[entityResult.Type] = values; } // The Entity type names are not consistent, map everything to camelcase so we can process them cleaner. dynamic entity = JObject.FromObject(entityResult); ((JArray)values).Add(entity.text); // get/create $instance JToken instanceRoot; if (!recognizerResult.Entities.TryGetValue("$instance", StringComparison.OrdinalIgnoreCase, out instanceRoot)) { instanceRoot = new JObject(); recognizerResult.Entities["$instance"] = instanceRoot; } // add instanceData JToken instanceData; if (!((JObject)instanceRoot).TryGetValue(entityResult.Type, StringComparison.OrdinalIgnoreCase, out instanceData)) { instanceData = new JArray(); instanceRoot[entityResult.Type] = instanceData; } dynamic instance = new JObject(); instance.startIndex = entity.start; instance.endIndex = entity.end; instance.score = (double)1.0; instance.text = entity.text; instance.type = entity.type; instance.resolution = entity.resolution; ((JArray)instanceData).Add(instance); } // if no match return None intent if (!recognizerResult.Intents.Keys.Any()) { recognizerResult.Intents.Add("None", new IntentScore() { Score = 1.0 }); } await dialogContext.Context.TraceActivityAsync(nameof(RegexRecognizer), JObject.FromObject(recognizerResult), "RecognizerResult", "Regex RecognizerResult", cancellationToken).ConfigureAwait(false); this.TrackRecognizerResult(dialogContext, "RegexRecognizerResult", this.FillRecognizerResultTelemetryProperties(recognizerResult, telemetryProperties), telemetryMetrics); return(recognizerResult); }