private async Task AfterContextualActionFinished(IDialogContext context, IAwaitable <ActionExecutionContext> executionContext) { var executionContextResult = await executionContext; if (executionContextResult.ChangeRootSignaling) { if (LuisActionResolver.IsContextualAction(this.luisAction)) { context.Done(executionContextResult); return; } else { this.intentName = executionContextResult.Intent; this.luisAction = executionContextResult.Action; } } else { var result = await executionContextResult.Action.FulfillAsync(); if (result is string) { await context.PostAsync(result.ToString()); } } await this.MessageReceivedAsync(context, null); }
public static async Task <QueryValueResult> QueryValueFromLuisAsync( ILuisService service, ILuisAction action, string paramName, object paramValue, CancellationToken token, Func <PropertyInfo, IEnumerable <EntityRecommendation>, EntityRecommendation> entityExtractor = null) { var originalValue = paramValue; service.ThrowIfNull(nameof(service)); action.ThrowIfNull(nameof(action)); service.ThrowIfNull(nameof(service)); paramValue.ThrowIfNull(nameof(paramValue)); if (string.IsNullOrWhiteSpace(paramName)) { throw new ArgumentNullException(nameof(paramName)); } var result = await service.QueryAsync(paramValue.ToString(), token); var queryIntent = result.Intents.FirstOrDefault(); if (!Intents.None.Equals(queryIntent.Intent, StringComparison.InvariantCultureIgnoreCase)) { var newAction = new LuisActionResolver(action.GetType().Assembly).ResolveActionFromLuisIntent(result, out string newIntentName); if (newAction != null && !newAction.GetType().Equals(action.GetType())) { return(new QueryValueResult(false) { NewAction = newAction, NewIntent = newIntentName }); } } var properties = new List <PropertyInfo> { action.GetType().GetProperty(paramName, BindingFlags.Public | BindingFlags.Instance) }; if (!AssignEntitiesToMembers(action, properties, result.Entities, entityExtractor)) { return(new QueryValueResult(AssignValue(action, properties.First(), originalValue))); } return(new QueryValueResult(true)); }
public virtual bool IsValid(out ICollection <ValidationResult> validationResults) { var context = new ValidationContext(this, null, null); validationResults = new List <ValidationResult>(); var result = Validator.TryValidateObject(this, context, validationResults, true); // do order properties validationResults = validationResults .OrderBy(r => { var paramAttrib = LuisActionResolver.GetParameterDefinition(this, r.MemberNames.First()); return(paramAttrib != null ? paramAttrib.Order : int.MaxValue); }) .ThenBy(r => r.MemberNames.First()) .ToList(); return(result); }
public static ILuisAction BuildContextForContextualAction(ILuisAction action, out string intentName) { action.ThrowIfNull(nameof(action)); if (!IsContextualAction(action)) { intentName = null; return(null); } var contextType = GetActionInterface(action) .First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ILuisContextualAction <>)) .GetGenericArguments()[0]; var result = Activator.CreateInstance(contextType) as ILuisAction; intentName = LuisActionResolver.GetActionDefinition(result).IntentName; var isContextual = false; LuisActionResolver.IsValidContextualAction(action, result, out isContextual); return(result); }
private async Task AfterOverrunCurrentActionSelected(IDialogContext context, IAwaitable <bool> result) { if (await result == true) { // if switching from contextual to other root if (LuisActionResolver.IsContextualAction(this.luisAction) && !LuisActionResolver.IsContextualAction(this.overrunData.NewAction)) { context.Done(new ActionExecutionContext(this.overrunData.NewIntent, this.overrunData.NewAction) { ChangeRootSignaling = true }); return; } this.intentName = this.overrunData.NewIntent; this.luisAction = this.overrunData.NewAction; } // clean overrunData - avoid serialization payload this.overrunData = null; await this.MessageReceivedAsync(context, null); }
protected virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> item) { var nextPromptIdx = 0; this.luisAction.IsValid(out ICollection <ValidationResult> validationResults); if (item != null) { var message = await item; var paramName = validationResults.First().MemberNames.First(); var paramValue = message.Text; var result = await LuisActionResolver.QueryValueFromLuisAsync(this.luisService, this.luisAction, paramName, paramValue, context.CancellationToken); if (result.Succeed) { nextPromptIdx++; } else if (!string.IsNullOrWhiteSpace(result.NewIntent) && result.NewAction != null) { var currentActionDefinition = LuisActionResolver.GetActionDefinition(this.luisAction); var isContextual = false; if (LuisActionResolver.IsValidContextualAction(result.NewAction, this.luisAction, out isContextual)) { var executionContextChain = new List <ActionExecutionContext> { new ActionExecutionContext(result.NewIntent, result.NewAction) }; var childDialog = new LuisActionMissingEntitiesDialog(this.luisService, executionContextChain); context.Call(childDialog, this.AfterContextualActionFinished); return; } else if (isContextual & !LuisActionResolver.IsContextualAction(this.luisAction)) { var newActionDefinition = LuisActionResolver.GetActionDefinition(result.NewAction); await context.PostAsync($"Cannot execute action '{newActionDefinition.FriendlyName}' in the context of '{currentActionDefinition.FriendlyName}' - continuing with current action"); } else if (!this.luisAction.GetType().Equals(result.NewAction.GetType())) { var newActionDefinition = LuisActionResolver.GetActionDefinition(result.NewAction); var valid = LuisActionResolver.UpdateIfValidContextualAction(result.NewAction, this.luisAction, out isContextual); if (!valid && isContextual) { await context.PostAsync($"Cannot switch to action '{newActionDefinition.FriendlyName}' from '{currentActionDefinition.FriendlyName}' due to invalid context - continuing with current action"); } else if (currentActionDefinition.ConfirmOnSwitchingContext) { // serialize overrun info this.overrunData = result; PromptDialog.Confirm( context, this.AfterOverrunCurrentActionSelected, $"Do you want to discard the current action '{currentActionDefinition.FriendlyName}' and start executing '{newActionDefinition.FriendlyName}' action?"); return; } else { this.intentName = result.NewIntent; this.luisAction = result.NewAction; this.luisAction.IsValid(out validationResults); } } } } if (validationResults.Count > nextPromptIdx) { await context.PostAsync(validationResults.ElementAt(nextPromptIdx).ErrorMessage); context.Wait(this.MessageReceivedAsync); } else { context.Done(new ActionExecutionContext(this.intentName, this.luisAction)); } }