Beispiel #1
0
        protected override async Task MessageReceived(IDialogContext context, IAwaitable <IMessageActivity> item)
        {
            var message     = await item;
            var messageText = await GetLuisQueryTextAsync(context, message);

            var tasks   = this.services.Select(s => s.QueryAsync(messageText, context.CancellationToken)).ToArray();
            var results = await Task.WhenAll(tasks);

            var winners = from result in results.Select((value, index) => new { value, index })
                          let resultWinner = this.BestIntentFrom(result.value)
                                             where resultWinner != null
                                             select new LuisServiceResult(result.value, resultWinner, this.services[result.index]);

            var winner = this.BestResultFrom(winners);

            if (winner == null)
            {
                throw new InvalidOperationException("No winning intent selected from Luis results.");
            }

            var intentName = default(string);
            var luisAction = this.actionResolver.ResolveActionFromLuisIntent(winner.Result, out intentName);

            if (luisAction != null)
            {
                var executionContextChain = new List <ActionExecutionContext> {
                    new ActionExecutionContext(intentName, luisAction)
                };
                while (LuisActionResolver.IsContextualAction(luisAction))
                {
                    var luisActionDefinition = default(LuisActionBindingAttribute);
                    if (!LuisActionResolver.CanStartWithNoContextAction(luisAction, out luisActionDefinition))
                    {
                        await context.PostAsync($"Cannot start contextual action '{luisActionDefinition.FriendlyName}' without a valid context.");

                        return;
                    }

                    luisAction = LuisActionResolver.BuildContextForContextualAction(luisAction, out intentName);
                    if (luisAction != null)
                    {
                        this.onContextCreation?.Invoke(luisAction, context);

                        executionContextChain.Insert(0, new ActionExecutionContext(intentName, luisAction));
                    }
                }

                var validationResults = default(ICollection <ValidationResult>); //check the validation result
                if (!luisAction.IsValid(out validationResults))
                {
                    var childDialog = new LuisActionMissingEntitiesDialog(winner.LuisService, executionContextChain);

                    context.Call(childDialog, this.LuisActionMissingDialogFinished);
                }
                else
                {
                    await this.DispatchToLuisActionActivityHandler(context, item, intentName, luisAction);
                }
            }
        }
Beispiel #2
0
            public virtual async Task StartAsync(IDialogContext context)
            {
                if (this.executionContextChain != null)
                {
                    var childDialog = new LuisActionMissingEntitiesDialog(this.luisService, this.executionContextChain);

                    // clean executionContextChain - avoid serialization payload
                    this.executionContextChain = null;

                    context.Call(childDialog, this.AfterContextualActionFinished);

                    return;
                }

                await this.MessageReceivedAsync(context, null);
            }
Beispiel #3
0
        protected override async Task MessageReceived(IDialogContext context, IAwaitable <IMessageActivity> item)
        {
            LuisServiceResult winner = await GetWinner(context, item);

            if (winner == null)
            {
                throw new InvalidOperationException("No winning intent selected from Luis results.");
            }

            ILuisAction luisAction = this.actionResolver.ResolveActionFromLuisIntent(winner.Result, out string intentName);

            if (luisAction != null)
            {
                var executionContextChain = new ActionExecutionContext(intentName, luisAction).ToSingleList();
                while (LuisActionResolver.IsContextualAction(luisAction))
                {
                    if (!LuisActionResolver.CanStartWithNoContextAction(luisAction, out LuisActionBindingAttribute luisActionDefinition))
                    {
                        await context.PostAsync($"Cannot start contextual action '{luisActionDefinition.FriendlyName}' without a valid context.");

                        return;
                    }

                    luisAction = LuisActionResolver.BuildContextForContextualAction(luisAction, out intentName);
                    if (luisAction != null)
                    {
                        this.onContextCreation?.Invoke(luisAction, context);
                        executionContextChain.Insert(0, new ActionExecutionContext(intentName, luisAction));
                    }
                }

                if (!luisAction.IsValid(out ICollection <ValidationResult> validationResults))
                {
                    var childDialog = new LuisActionMissingEntitiesDialog(winner.LuisService, executionContextChain);
                    context.Call(childDialog, this.LuisActionMissingDialogFinished);
                }
                else
                {
                    await this.DispatchToLuisActionActivityHandler(context, item, intentName, luisAction);
                }
            }
        }
Beispiel #4
0
            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));
                }
            }