protected virtual async Task <object> PerformActionFulfillment(IDialogContext context, IAwaitable <IMessageActivity> item, ILuisAction luisAction) { var message = await item; return(await luisAction.FulfillAsync(context, message.Text)); }
protected virtual async Task DispatchToLuisActionActivityHandler(IDialogContext context, IAwaitable <IMessageActivity> item, string intentName, ILuisAction luisAction) { var actionHandlerByIntent = new Dictionary <string, LuisActionActivityHandler>(this.GetActionHandlersByIntent()); var handler = default(LuisActionActivityHandler); if (!actionHandlerByIntent.TryGetValue(intentName, out handler)) { handler = actionHandlerByIntent[string.Empty]; } if (handler != null) { await handler(context, item, await this.PerformActionFulfillment(context, item, luisAction)); } else { throw new Exception($"No default intent handler found."); } }
protected virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> item) { var nextPromptIdx = 0; var validationResults = default(ICollection <ValidationResult>); this.luisAction.IsValid(out 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)); } }
private static bool AssignEntitiesToMembers( ILuisAction action, IEnumerable <PropertyInfo> properties, IEnumerable <EntityRecommendation> entities, Func <PropertyInfo, IEnumerable <EntityRecommendation>, EntityRecommendation> entityExtractor = null) { var result = true; if (action == null) { throw new ArgumentNullException(nameof(action)); } if (properties == null) { throw new ArgumentNullException(nameof(properties)); } if (entities == null) { throw new ArgumentNullException(nameof(entities)); } if (!entities.Any()) { return(!result); } // Cross match entities to copy resolution values for custom entities from pairs foreach (var group in entities.GroupBy(e => e.Entity)) { if (group.Count() > 1) { var entityToUpdate = group.FirstOrDefault(e => !BuiltInTypes.IsBuiltInType(e.Type)); var entityWithValue = group.FirstOrDefault(e => e.Resolution != null); if (entityToUpdate != null && entityWithValue != null) { entityToUpdate.Resolution = entityWithValue.Resolution; } } } foreach (var property in properties) { var matchingEntity = default(EntityRecommendation); var matchingEntities = default(IEnumerable <EntityRecommendation>); // Find using custom type from attrib if available var paramAttrib = property.GetCustomAttributes <LuisActionBindingParamAttribute>(true).FirstOrDefault(); if (paramAttrib != null) { matchingEntities = entities.Where(e => e.Type == paramAttrib.CustomType); } // Find using property name if (matchingEntities == null || !matchingEntities.Any()) { matchingEntities = entities.Where(e => e.Type == property.Name); } // Find using builtin type from attrib if available if ((matchingEntities == null || !matchingEntities.Any()) && paramAttrib != null) { matchingEntities = entities.Where(e => e.Type == paramAttrib.BuiltinType); } // If callback available then use it if (matchingEntities.Count() > 1) { if (entityExtractor != null) { matchingEntity = entityExtractor(property, matchingEntities); } } else { matchingEntity = matchingEntities.FirstOrDefault(); } // Prioritize resolution if (matchingEntity != null) { object paramValue = null; if (matchingEntity.Resolution != null && matchingEntity.Resolution.Count > 0) { var resolutionValue = matchingEntity.Resolution.First().Value; if (resolutionValue is IList <object> ) { // multiple resolution values - datetimev2 var dateTimeResolutionValues = GetDateTimeValues(matchingEntity); paramValue = dateTimeResolutionValues["value"]; } if (paramValue == null) { // other built-in with single resolution value paramValue = resolutionValue; } } else { paramValue = matchingEntity.Entity; } result &= AssignValue(action, property, paramValue); } else if (matchingEntities.Count() > 0 && matchingEntities.Count(e => e.Resolution != null && e.Resolution.First().Value is JArray) == matchingEntities.Count()) { var paramValues = new JArray(); foreach (var currentMatchingEntity in matchingEntities) { var values = currentMatchingEntity.Resolution.First().Value as JArray; foreach (var value in values) { paramValues.Add(value); } } result &= AssignValue(action, property, paramValues); } else { result = false; } } return(result); }
private static Type[] GetActionInterface(ILuisAction action) { return(action.GetType().GetInterfaces()); }
public static bool IsContextualAction(ILuisAction action) { action.ThrowIfNull(nameof(action)); return(GetActionInterface(action).Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ILuisContextualAction <>))); }
private static bool FindEntity(ILuisAction action, IEnumerable <PropertyInfo> properties, IEnumerable <EntityRecommendation> entities, Func <PropertyInfo, IEnumerable <EntityRecommendation>, EntityRecommendation> entityExtractor) { bool result = true; foreach (var property in properties) { var matchingEntity = default(EntityRecommendation); var matchingEntities = default(IEnumerable <EntityRecommendation>); var paramAttrib = property.GetCustomAttributes <LuisActionBindingParamAttribute>(true).FirstOrDefault(); // Find using custom type from attrib if available if (paramAttrib != null) { matchingEntities = entities.Where(e => e.Type == paramAttrib.CustomType); } // Find using property name if (matchingEntities != null || !matchingEntities.Any()) { matchingEntities = entities.Where(e => e.Type == property.Name); } // Find using builtin type from attrib if available if ((matchingEntities != null || !matchingEntities.Any()) && paramAttrib != null) { matchingEntities = entities.Where(e => e.Type == paramAttrib.BuiltinType); } // If callback available then use it if (matchingEntities.Count() > 1) { matchingEntity = entityExtractor?.Invoke(property, matchingEntities); } else { matchingEntity = matchingEntities.FirstOrDefault(); } // Prioritize resolution if (matchingEntity != null) { var paramValue = matchingEntity.Resolution != null && matchingEntity.Resolution.Count > 0 ? matchingEntity.Resolution.First().Value : matchingEntity.Entity; result &= AssignValue(action, property, paramValue); } else if (matchingEntities.Count() > 0 && matchingEntities.Count(e => e.Resolution != null && e.Resolution.First().Value is JArray) == matchingEntities.Count()) { var paramValues = new JArray(); foreach (var currentMatchingEntity in matchingEntities) { var values = currentMatchingEntity.Resolution.First().Value as JArray; foreach (var value in values) { paramValues.Add(value); } } result &= AssignValue(action, property, paramValues); } else { result = false; } } return(result); }
protected virtual async Task <object> PerformActionFulfillment(IDialogContext context, IMessageActivity item, ILuisAction luisAction) { return(await luisAction.FulfillAsync()); }
/// <summary> /// Construct the Action Context. /// </summary> /// <param name="intent">The LUIS Intent name that triggered the action.</param> /// <param name="action">The LUIS Action Binding model that was triggered.</param> public ActionExecutionContext(string intent, ILuisAction action) { this.Intent = intent; this.Action = action; }