Exemplo n.º 1
0
        private Dialog WrapDialogForPropertyMocks(Dialog dialog)
        {
            string settingsPrefix      = $"{ScopePath.Settings}.";
            var    setPropertiesDialog = new SetProperties();
            var    hasSet = new HashSet <string>();

            foreach (var property in PropertyMocks)
            {
                if (property is PropertiesMock mock)
                {
                    foreach (var assignment in mock.Assignments)
                    {
                        // Note we only check if it is for settings here.
                        if (!assignment.Property.StartsWith(settingsPrefix, StringComparison.Ordinal))
                        {
                            if (!hasSet.Contains(assignment.Property))
                            {
                                setPropertiesDialog.Assignments.Add(new Adaptive.Actions.PropertyAssignment
                                {
                                    Property = new StringExpression(assignment.Property),
                                    Value    = new ValueExpression(assignment.Value)
                                });

                                hasSet.Add(assignment.Property);
                            }
                        }
                    }
                }
            }

            if (hasSet.Count == 0)
            {
                return(dialog);
            }
            else
            {
                var rootDialog = new AdaptiveDialog();
                rootDialog.Triggers.Add(new OnBeginDialog
                {
                    Actions = new List <Dialog>
                    {
                        setPropertiesDialog,
                        new ReplaceDialog
                        {
                            Dialog = dialog
                        }
                    }
                });

                return(rootDialog);
            }
        }
Exemplo n.º 2
0
        private void LoadDialogs()
        {
            System.Diagnostics.Trace.TraceInformation("Loading resources...");

            // normally you just look up your root dialog and load it
            //var resource = this.resourceExplorer.GetResource("myroot.dialog");
            //this.rootDialog = DeclarativeTypeLoader.Load<AdaptiveDialog>(resource, this.resourceExplorer, DebugSupport.SourceRegistry);

            // but for this sample we enumerate all of the .main.dialog files and build a ChoiceInput as our rootidialog.
            this.rootDialog = CreateChoiceInputForAllMainDialogs();

            System.Diagnostics.Trace.TraceInformation("Done loading resources.");
        }
Exemplo n.º 3
0
        private TestFlow CreateFlow(string locale)
        {
            TypeFactory.Configuration = new ConfigurationBuilder().Build();
            var storage          = new MemoryStorage();
            var convoState       = new ConversationState(storage);
            var userState        = new UserState(storage);
            var resourceExplorer = new ResourceExplorer();
            var adapter          = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName));

            adapter
            .UseStorage(storage)
            .UseState(userState, convoState)
            .UseResourceExplorer(resourceExplorer)
            .UseAdaptiveDialogs()
            .UseLanguageGeneration(resourceExplorer)
            .UseAdaptiveDialogs()
            .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger()));

            adapter.Locale = locale;

            var dialog = new AdaptiveDialog();

            dialog.Recognizer = GetMultiLingualRecognizer();
            dialog.Triggers.AddRange(new List <OnCondition>()
            {
                new OnIntent("Greeting", actions:
                             new List <Dialog>()
                {
                    new SendActivity("greeting intent"),
                }),
                new OnIntent("Goodbye", actions:
                             new List <Dialog>()
                {
                    new SendActivity("goodbye intent"),
                }),
                new OnUnknownIntent(actions:
                                    new List <Dialog>()
                {
                    new SendActivity("default rule"),
                }),
            });
            DialogManager dm = new DialogManager(dialog);

            return(new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                await dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false);
            }));
        }
        public UserProfileDialog()
            : base(nameof(UserProfileDialog))
        {
            // Create instance of adaptive dialog.
            var rootDialog = new AdaptiveDialog(nameof(AdaptiveDialog))
            {
                // These steps are executed when this Adaptive Dialog begins
                Steps = OnBeginDialogSteps(),
            };

            // Add named dialogs to the DialogSet. These names are saved in the dialog state.
            AddDialog(rootDialog);

            // The initial child Dialog to run.
            InitialDialogId = nameof(AdaptiveDialog);
        }
Exemplo n.º 5
0
        public async Task Action_TelemetryTrackEvent()
        {
            var mockTelemetryClient = new Mock <IBotTelemetryClient>();

            var testAdapter = new TestAdapter()
                              .UseStorage(new MemoryStorage())
                              .UseBotState(new ConversationState(new MemoryStorage()), new UserState(new MemoryStorage()));

            var rootDialog = new AdaptiveDialog
            {
                Triggers = new List <OnCondition>()
                {
                    new OnBeginDialog()
                    {
                        Actions = new List <Dialog>()
                        {
                            new TelemetryTrackEventAction("testEvent")
                            {
                                Properties =
                                    new Dictionary <string, AdaptiveExpressions.Properties.
                                                    StringExpression>()
                                {
                                    { "prop1", "value1" },
                                    { "prop2", "value2" }
                                }
                            },
                        }
                    }
                },
                TelemetryClient = mockTelemetryClient.Object
            };

            var dm = new DialogManager(rootDialog)
                     .UseResourceExplorer(new ResourceExplorer())
                     .UseLanguageGeneration();

            await new TestFlow((TestAdapter)testAdapter, dm.OnTurnAsync)
            .SendConversationUpdate()
            .StartTestAsync();

            var testEventInvocation = mockTelemetryClient.Invocations.FirstOrDefault(i => i.Arguments[0]?.ToString() == "testEvent");

            Assert.NotNull(testEventInvocation);
            Assert.Equal(2, ((Dictionary <string, string>)testEventInvocation.Arguments[1]).Count);
            Assert.Equal("value1", ((Dictionary <string, string>)testEventInvocation.Arguments[1])["prop1"]);
            Assert.Equal("value2", ((Dictionary <string, string>)testEventInvocation.Arguments[1])["prop2"]);
        }
Exemplo n.º 6
0
        private AdaptiveDialog CreateChoiceInputForAllMainDialogs()
        {
            var dialogChoices = new List <Choice>();
            var dialogCases   = new List <Case>();

            foreach (var resource in this.resourceExplorer.GetResources(".dialog").Where(r => r.Id.EndsWith(".main.dialog")))
            {
                var name = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(resource.Id));
                dialogChoices.Add(new Choice(name));
                var subDialog = DeclarativeTypeLoader.Load <AdaptiveDialog>(resource, resourceExplorer, DebugSupport.SourceMap);
                dialogCases.Add(new Case($"{name}", new List <Dialog>()
                {
                    subDialog
                }));
            }

            var dialog = new AdaptiveDialog()
            {
                AutoEndDialog = false,
                Triggers      = new List <OnCondition>()
                {
                    new OnBeginDialog()
                    {
                        Actions = new List <Dialog>()
                        {
                            new ChoiceInput()
                            {
                                Prompt       = new ActivityTemplate("What declarative sample do you want to run?"),
                                Property     = "conversation.dialogChoice",
                                AlwaysPrompt = true,
                                Style        = ListStyle.List,
                                Choices      = new ChoiceSet(dialogChoices)
                            },
                            new SendActivity("# Running {conversation.dialogChoice}.main.dialog"),
                            new SwitchCondition()
                            {
                                Condition = "conversation.dialogChoice",
                                Cases     = dialogCases
                            },
                            new RepeatDialog()
                        }
                    }
                }
            };

            return(dialog);
        }
Exemplo n.º 7
0
        public ViewToDoDialog()
            : base(nameof(ViewToDoDialog))
        {
            // Create instance of adaptive dialog.
            var ViewToDoDialog = new AdaptiveDialog(nameof(AdaptiveDialog))
            {
                Steps = new List <IDialog>()
                {
                    new SendActivity("[View-ToDos]")
                }
            };

            // Add named dialogs to the DialogSet. These names are saved in the dialog state.
            AddDialog(ViewToDoDialog);

            // The initial child Dialog to run.
            InitialDialogId = nameof(AdaptiveDialog);
        }
Exemplo n.º 8
0
        public RootDialog() : base(nameof(RootDialog))
        {
            string[] path     = { ".", "Template", "simple.lg" };
            var      fullpath = Path.Combine(path);

            var rootDialog = new AdaptiveDialog
            {
                Generator  = new TemplateEngineLanguageGenerator(Templates.ParseFile(fullpath)),
                Recognizer = CreateRecognizer(),
                Triggers   = new List <OnCondition>
                {
                    new OnIntent()
                    {
                        Intent  = "book",
                        Actions = new List <Dialog>()
                        {
                            new SendActivity("${Book()}")
                        }
                    },

                    new OnIntent()
                    {
                        Intent  = "weather",
                        Actions = new List <Dialog>()
                        {
                            new SendActivity("${Weather()}")
                        }
                    },

                    new OnUnknownIntent()
                    {
                        Actions = new List <Dialog>()
                        {
                            new SendActivity("${Unknown()}")
                        }
                    }
                }
            };

            AddDialog(rootDialog);

            InitialDialogId = nameof(AdaptiveDialog);
        }
        public async Task OnActivityTypes()
        {
            var planningDialog = new AdaptiveDialog("planningTest")
            {
                AutoEndDialog = false,
                Triggers      = new List <OnCondition>()
                {
                    TestCondition(new OnMessageActivity()),
                    TestCondition(new OnEventActivity()),
                    TestCondition(new OnConversationUpdateActivity()),
                    TestCondition(new OnTypingActivity()),
                    TestCondition(new OnEndOfConversationActivity()),
                    TestCondition(new OnEventActivity()),
                    TestCondition(new OnHandoffActivity()),
                    TestCondition(new OnMessageReactionActivity()),
                    TestCondition(new OnMessageUpdateActivity()),
                    TestCondition(new OnMessageDeleteActivity()),
                }
            };

            await CreateFlow(planningDialog)
            .Send(new Activity(ActivityTypes.Message, text: nameof(OnMessageActivity)))
            .AssertReply(nameof(OnMessageActivity))
            .Send(new Activity(ActivityTypes.MessageReaction, text: nameof(OnMessageReactionActivity)))
            .AssertReply(nameof(OnMessageReactionActivity))
            .Send(new Activity(ActivityTypes.MessageDelete, text: nameof(OnMessageDeleteActivity)))
            .AssertReply(nameof(OnMessageDeleteActivity))
            .Send(new Activity(ActivityTypes.MessageUpdate, text: nameof(OnMessageUpdateActivity)))
            .AssertReply(nameof(OnMessageUpdateActivity))
            .Send(new Activity(ActivityTypes.Typing, text: nameof(OnTypingActivity)))
            .AssertReply(nameof(OnTypingActivity))
            .Send(new Activity(ActivityTypes.ConversationUpdate, text: nameof(OnConversationUpdateActivity)))
            .AssertReply(nameof(OnConversationUpdateActivity))
            .Send(new Activity(ActivityTypes.EndOfConversation, text: nameof(OnEndOfConversationActivity)))
            .AssertReply(nameof(OnEndOfConversationActivity))
            .Send(new Activity(ActivityTypes.Event, text: nameof(OnEventActivity))
            {
                Name = nameof(OnEventActivity)
            })
            .AssertReply(nameof(OnEventActivity))
            .StartTestAsync();
        }
Exemplo n.º 10
0
        public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
        {
            AdaptiveDialog rootDialog = (AdaptiveDialog)this.dialogManager.RootDialog;

            if (turnContext.TurnState.Get <IIdentity>(BotAdapter.BotIdentityKey) is ClaimsIdentity claimIdentity && SkillValidation.IsSkillClaim(claimIdentity.Claims))
            {
                rootDialog.AutoEndDialog = true;
            }

            if (this.removeRecipientMention && turnContext?.Activity?.Type == "message")
            {
                turnContext.Activity.RemoveRecipientMention();
            }

            await this.dialogManager.OnTurnAsync(turnContext, cancellationToken : cancellationToken);

            await this.conversationState.SaveChangesAsync(turnContext, false, cancellationToken);

            await this.userState.SaveChangesAsync(turnContext, false, cancellationToken);
        }
Exemplo n.º 11
0
        private void LoadDialogs()
        {
            System.Diagnostics.Trace.TraceInformation("Loading resources...");

            this.rootDialog = new AdaptiveDialog()
            {
                AutoEndDialog = false,
                Steps         = new List <IDialog>()
            };
            var choiceInput = new ChoiceInput()
            {
                Prompt        = new ActivityTemplate("What declarative sample do you want to run?"),
                OutputBinding = "conversation.dialogChoice",
                AlwaysPrompt  = true,
                Choices       = new List <Choice>()
            };

            var handleChoice = new SwitchCondition()
            {
                Condition = "conversation.dialogChoice",
                Cases     = new List <Case>()
            };

            foreach (var resource in this.resourceExplorer.GetResources(".dialog").Where(r => r.Id.EndsWith(".main.dialog")))
            {
                var name = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(resource.Id));
                choiceInput.Choices.Add(new Choice(name));
                var dialog = DeclarativeTypeLoader.Load <IDialog>(resource, this.resourceExplorer, DebugSupport.SourceRegistry);
                handleChoice.Cases.Add(new Case($"'{name}'", new List <IDialog>()
                {
                    dialog
                }));
            }
            choiceInput.Style = ListStyle.Auto;
            this.rootDialog.Steps.Add(choiceInput);
            this.rootDialog.Steps.Add(new SendActivity("# Running {conversation.dialogChoice}.main.dialog"));
            this.rootDialog.Steps.Add(handleChoice);
            this.rootDialog.Steps.Add(new RepeatDialog());

            System.Diagnostics.Trace.TraceInformation("Done loading resources.");
        }
Exemplo n.º 12
0
        public async Task OnIntent()
        {
            var planningDialog = new AdaptiveDialog("planningTest")
            {
                AutoEndDialog = false,
                Recognizer    = new RegexRecognizer()
                {
                    Intents = new List <IntentPattern>()
                    {
                        new IntentPattern("JokeIntent", "joke"),
                    }
                },
                Triggers = new List <OnCondition>()
                {
                    new OnBeginDialog()
                    {
                        Actions = new List <Dialog>()
                        {
                            new SendActivity("I'm a joke bot. To get started say 'tell me a joke'")
                        },
                    },
                    new OnIntent(
                        "JokeIntent",
                        actions: new List <Dialog>()
                    {
                        new SendActivity("Why did the chicken cross the road?"),
                        new EndTurn(),
                        new SendActivity("To get to the other side")
                    }),
                }
            };

            await CreateFlow(planningDialog)
            .SendConversationUpdate()
            .AssertReply("I'm a joke bot. To get started say 'tell me a joke'")
            .Send("Do you know a joke?")
            .AssertReply("Why did the chicken cross the road?")
            .Send("Why?")
            .AssertReply("To get to the other side")
            .StartTestAsync();
        }
Exemplo n.º 13
0
        public ViewToDoDialog()
            : base(nameof(ViewToDoDialog))
        {
            string[] paths    = { ".", "Dialogs", "ViewToDoDialog", "ViewToDoDialog.lg" };
            string   fullPath = Path.Combine(paths);
            // Create instance of adaptive dialog.
            var ViewToDoDialog = new AdaptiveDialog(nameof(AdaptiveDialog))
            {
                Generator = new TemplateEngineLanguageGenerator(new TemplateEngine().AddFile(fullPath)),
                Steps     = new List <IDialog>()
                {
                    new SendActivity("[View-ToDos]")
                }
            };

            // Add named dialogs to the DialogSet. These names are saved in the dialog state.
            AddDialog(ViewToDoDialog);

            // The initial child Dialog to run.
            InitialDialogId = nameof(AdaptiveDialog);
        }
Exemplo n.º 14
0
        public async Task OnIntentWithEntities()
        {
            var planningDialog = new AdaptiveDialog("planningTest")
            {
                AutoEndDialog = false,
                Recognizer    = new RegexRecognizer()
                {
                    Intents = new List <IntentPattern>()
                    {
                        new IntentPattern("addColor", "I want (?<color>(red|green|blue|yellow))*"),
                    }
                },
                Triggers = new List <OnCondition>()
                {
                    new OnIntent(
                        intent: "addColor",
                        entities: new List <string>()
                    {
                        "color"
                    },
                        actions: new List <Dialog>()
                    {
                        new SendActivity("You picked {@color}")
                    }),
                    new OnUnknownIntent(actions: new List <Dialog>()
                    {
                        new SendActivity("pbtpbtpbt!")
                    })
                }
            };

            await CreateFlow(planningDialog)
            .Send("I want red")
            .AssertReply("You picked red")
            .Send("I want")
            .AssertReply("pbtpbtpbt!")
            .Send("fooo")
            .AssertReply("pbtpbtpbt!")
            .StartTestAsync();
        }
Exemplo n.º 15
0
        private AdaptiveDialog CreateChoiceInputForAllMainDialogs()
        {
            var dialog = new AdaptiveDialog()
            {
                AutoEndDialog = false,
                Steps         = new List <IDialog>()
            };
            var choiceInput = new ChoiceInput()
            {
                Prompt       = new ActivityTemplate("What declarative sample do you want to run?"),
                Property     = "conversation.dialogChoice",
                AlwaysPrompt = true,
                Choices      = new List <Choice>(),
            };

            var handleChoice = new SwitchCondition()
            {
                Condition = "conversation.dialogChoice",
                Cases     = new List <Case>()
            };

            foreach (var resource in this.resourceExplorer.GetResources(".dialog").Where(r => r.Id.EndsWith(".main.dialog")))
            {
                var name = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(resource.Id));
                choiceInput.Choices.Add(new Choice(name));
                var subDialog = DeclarativeTypeLoader.Load <IDialog>(resource, this.resourceExplorer, DebugSupport.SourceRegistry);
                handleChoice.Cases.Add(new Case($"{name}", new List <IDialog>()
                {
                    subDialog
                }));
            }
            choiceInput.Style = ListStyle.List;
            dialog.Steps.Add(choiceInput);
            dialog.Steps.Add(new SendActivity("# Running {conversation.dialogChoice}.main.dialog"));
            dialog.Steps.Add(handleChoice);
            dialog.Steps.Add(new RepeatDialog());
            return(dialog);
        }
Exemplo n.º 16
0
        public RootDialog(IConfiguration configuration)
            : base(nameof(RootDialog))
        {
            // Create instance of adaptive dialog.
            var rootDialog = new AdaptiveDialog(nameof(AdaptiveDialog))
            {
                // There are no steps associated with this dialog.
                // This dialog will react to user input using its own Recognizer's output and Rules.

                // Add a recognizer to this adaptive dialog.
                // For this dialog, we will use the LUIS recognizer based on the FlightBooking.json
                // found under CognitiveModels folder.
                Recognizer = CreateRecognizer(configuration),
                // Add rules to respond to different events of interest
                Rules = CreateRules()
            };

            // Add named dialogs to the DialogSet. These names are saved in the dialog state.
            AddDialog(rootDialog);

            // The initial child Dialog to run.
            InitialDialogId = nameof(AdaptiveDialog);
        }
Exemplo n.º 17
0
        public RootDialog()
            : base(nameof(RootDialog))
        {
            string[] paths    = { ".", "Dialogs", "RootDialog.LG" };
            string   fullPath = Path.Combine(paths);

            // Create instance of adaptive dialog.
            var rootDialog = new AdaptiveDialog(nameof(AdaptiveDialog))
            {
                Rules = new List <IRule> ()
                {
                    // Add a rule to welcome user
                    new ConversationUpdateActivityRule()
                    {
                        Steps = WelcomeUserSteps()
                    },

                    // Respond to user on message activity
                    new EventRule()
                    {
                        Events = new List <String> ()
                        {
                            AdaptiveEvents.BeginDialog
                        },
                        Constraint = $"turn.activity.type == '{ActivityTypes.Message}'",
                        Steps      = OnBeginDialogSteps()
                    }
                },
                Generator = new TemplateEngineLanguageGenerator(new TemplateEngine().AddFile(fullPath))
            };

            // Add named dialogs to the DialogSet. These names are saved in the dialog state.
            AddDialog(rootDialog);

            // The initial child Dialog to run.
            InitialDialogId = nameof(AdaptiveDialog);
        }
Exemplo n.º 18
0
        public async Task DialogManager_ContainerRegistration()
        {
            var root = new AdaptiveDialog("root")
            {
                Triggers = new List <OnCondition>
                {
                    new OnBeginDialog()
                    {
                        Actions = new List <Dialog> {
                            new AdaptiveDialog("inner")
                        }
                    }
                }
            };

            var storage    = new MemoryStorage();
            var convoState = new ConversationState(storage);
            var userState  = new UserState(storage);

            var adapter = new TestAdapter();

            adapter
            .UseStorage(storage)
            .UseBotState(userState, convoState);

            // The inner adaptive dialog should be registered on the DialogManager after OnTurn
            var dm = new DialogManager(root);

            await new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                await dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false);
            })
            .SendConversationUpdate()
            .StartTestAsync();

            Assert.NotNull(dm.Dialogs.Find("inner"));
        }
Exemplo n.º 19
0
        public async Task DialogManager_ContainerRegistration_OnCyclicalDialogStructures()
        {
            var root = new AdaptiveDialog("root")
            {
                Triggers = new List <OnCondition>
                {
                    new OnBeginDialog()
                }
            };

            (root.Triggers.Single() as OnBeginDialog).Actions = new List <Dialog> {
                new EndTurn(), root
            };

            var storage    = new MemoryStorage();
            var convoState = new ConversationState(storage);
            var userState  = new UserState(storage);

            var adapter = new TestAdapter();

            adapter
            .UseStorage(storage)
            .UseBotState(userState, convoState);

            // The inner adaptive dialog should be registered on the DialogManager after OnTurn.
            var dm = new DialogManager(root);

            await new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                // First OnTurn invocation will trigger registration of dependencies.
                // If registration is not protected against cyclical dialog structures,
                // this call will throw StackOverflowException.
                await dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false);
            })
            .SendConversationUpdate()
            .StartTestAsync();
        }
Exemplo n.º 20
0
        public RootDialog(UserState userState) : base("root")
        {
            _userState = userState;

            AddDialog(new UserProfileDialog(userState));
            AddDialog(new LocationDialog());

            // The initial child Dialog to run.
            InitialDialogId = "waterfall";

            // Get Folder of dialogs.
            var resourceExplorer = new ResourceExplorer().AddFolder("Dialogs");

            // find the main composer dialog to start with
            var composerDialog = resourceExplorer.GetResource("Main.dialog");
            // hyrdate an Adaptive Dialogue
            AdaptiveDialog myComposerDialog = DeclarativeTypeLoader.Load <AdaptiveDialog>(composerDialog, resourceExplorer, DebugSupport.SourceMap);

            myComposerDialog.Id = "Main.dialog";
            // setup lanaguage generation for the dialogue
            myComposerDialog.Generator = new TemplateEngineLanguageGenerator(new TemplateEngine().AddFile(@"C:\Users\Jamie\source\repos\composer-and-adaptive\SharingState\Dialogs\ComposerDialogs\Main\Main.lg"));
            // add to the ComponentDialog which Root dialogue inherits from
            AddDialog(myComposerDialog);

            var composerLocationDialog = resourceExplorer.GetResource("ProcessLocation.dialog");
            // hyrdate an Adaptive Dialogue
            AdaptiveDialog myComposerLocationDialog = DeclarativeTypeLoader.Load <AdaptiveDialog>(composerLocationDialog, resourceExplorer, DebugSupport.SourceMap);

            myComposerLocationDialog.Id = "ProcessLocation.dialog";
            // setup lanaguage generation for the dialogue
            myComposerLocationDialog.Generator = new TemplateEngineLanguageGenerator(new TemplateEngine().AddFile(@"C:\Users\Jamie\source\repos\composer-and-adaptive\SharingState\Dialogs\ComposerDialogs\ProcessLocation\ProcessLocation.lg"));
            // add to the ComponentDialog which Root dialogue inherits from
            AddDialog(myComposerLocationDialog);

            AddDialog(new WaterfallDialog("waterfall", new WaterfallStep[] { StartDialogAsync, BeginComposerAdaptiveDialog, BeginComposerLocationAdaptiveDialog, ReadLocationFromComposerDialog }));
        }
Exemplo n.º 21
0
        public async Task DialogContextState_SettingsTest()
        {
            var dialog = new AdaptiveDialog();

            dialog.Triggers.AddRange(new List <OnCondition>()
            {
                new OnUnknownIntent(actions:
                                    new List <Dialog>()
                {
                    new SendActivity()
                    {
                        Activity = new ActivityTemplate("@{settings.ApplicationInsights.InstrumentationKey}")
                    },
                }),
            });
            await CreateFlow("en-us", dialog)
            .Send("howdy")
            .AssertReply("00000000-0000-0000-0000-000000000000")
            .Send("howdy")
            .AssertReply("00000000-0000-0000-0000-000000000000")
            .Send("howdy")
            .AssertReply("00000000-0000-0000-0000-000000000000")
            .StartTestAsync();
        }
Exemplo n.º 22
0
        public RootDialog(UserState userState) : base("root")
        {
            _userState = userState;

            // Get Folder of dialogs.
            var resourceExplorer = new ResourceExplorer().AddFolder(@"Dialogs");

            // find the main composer dialog to start with
            var composerDialog = resourceExplorer.GetResource("Main.dialog");

            // hyrdate an Adaptive Dialogue
            AdaptiveDialog myComposerDialog = DeclarativeTypeLoader.Load <AdaptiveDialog>(composerDialog, resourceExplorer, DebugSupport.SourceMap);

            myComposerDialog.Id = "Main.dialog";

            // setup lanaguage generation for the dialogue
            myComposerDialog.Generator = new TemplateEngineLanguageGenerator(new TemplateEngine().AddFile(@"Dialogs\ComposerDialogs\Main\Main.lg"));

            // add to the ComponentDialog which Root dialogue inherits from
            AddDialog(myComposerDialog);

            // create a waterfall dialogue and begin our adaptive dialogue
            AddDialog(new WaterfallDialog("waterfall", new WaterfallStep[] { BeginComposerAdaptiveDialog }));
        }
Exemplo n.º 23
0
        private TestFlow CreateFlow(AdaptiveDialog dialog, bool sendTrace = false)
        {
            TypeFactory.Configuration = new ConfigurationBuilder().Build();
            var resourceExplorer = new ResourceExplorer();
            var storage          = new MemoryStorage();
            var convoState       = new ConversationState(storage);
            var userState        = new UserState(storage);
            var adapter          = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName), sendTrace);

            adapter
            .UseStorage(storage)
            .UseState(userState, convoState)
            .UseResourceExplorer(resourceExplorer)
            .UseLanguageGeneration(resourceExplorer)
            .UseAdaptiveDialogs()
            .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger()));

            DialogManager dm = new DialogManager(dialog);

            return(new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                await dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false);
            }));
        }
        private TestFlow CreateFlow(string locale)
        {
            var convoState = new ConversationState(new MemoryStorage());
            var userState  = new UserState(new MemoryStorage());
            var dialog     = new AdaptiveDialog();

            dialog.Triggers.AddRange(new List <OnCondition>()
            {
                new OnUnknownIntent(actions:
                                    new List <Dialog>()
                {
                    new SendActivity()
                    {
                        Activity = new ActivityTemplate("{settings.ApplicationInsights.InstrumentationKey}")
                    },
                }),
            });

            var resourceExplorer = new ResourceExplorer();

            var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                          .Use(new RegisterClassMiddleware <ResourceExplorer>(resourceExplorer))
                          .Use(new RegisterClassMiddleware <IStorage>(new MemoryStorage()))
                          .UseAdaptiveDialogs()
                          .UseLanguageGeneration(resourceExplorer)
                          .Use(new RegisterClassMiddleware <IConfiguration>(this.Configuration))
                          .Use(new AutoSaveStateMiddleware(convoState, userState))
                          .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger()));

            DialogManager dm = new DialogManager(dialog);

            return(new TestFlow((TestAdapter)adapter, async(turnContext, cancellationToken) =>
            {
                await dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false);
            }));
        }
        public async Task TestLGScopedAccess()
        {
            var dialog = new AdaptiveDialog()
            {
                Id        = "AdaptiveDialog1",
                Generator = new ResourceMultiLanguageGenerator("subDialog.lg"),
                Triggers  = new List <OnCondition>()
                {
                    new OnBeginDialog()
                    {
                        Actions = new List <Dialog>()
                        {
                            new AssertLGDialog()
                            {
                                Id = "test1", ResourceId = "subDialog.lg"
                            },
                            new BeginDialog()
                            {
                                Dialog = new AdaptiveDialog()
                                {
                                    Id        = "AdaptiveDialog2",
                                    Generator = new ResourceMultiLanguageGenerator("test.lg"),
                                    Triggers  = new List <OnCondition>()
                                    {
                                        new OnBeginDialog()
                                        {
                                            Actions = new List <Dialog>()
                                            {
                                                new AssertLGDialog()
                                                {
                                                    Id = "test2", ResourceId = "test.lg"
                                                },
                                            }
                                        }
                                    }
                                }
                            },
                            new AssertLGDialog()
                            {
                                Id = "test3", ResourceId = "subDialog.lg"
                            },
                            new SendActivity("Done")
                        }
                    }
                }
            };
            var resourceExplorer = new ResourceExplorer()
                                   .LoadProject(GetProjectFolder(), monitorChanges: false);

            DialogManager dm = new DialogManager(dialog)
                               .UseResourceExplorer(resourceExplorer)
                               .UseLanguageGeneration("test.lg");

            await CreateFlow(async (turnContext, cancellationToken) =>
            {
                System.Diagnostics.Trace.TraceInformation($"BEGIN TURN {turnContext.Activity.Text}");
                await dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false);
                System.Diagnostics.Trace.TraceInformation($"END TURN {turnContext.Activity.Text}");
            })
            // inside AdaptiveDialog1
            .Send("turn1")
            .AssertReply("BeginDialog test1:subDialog.lg")
            .Send("turn2")
            .AssertReply("ContinueDialog test1:subDialog.lg")
            // inside AdaptiveDialog2
            .AssertReply("BeginDialog test2:test.lg")
            .Send("turn3")
            .AssertReply("ContinueDialog test2:test.lg")
            // back out to AdaptiveDialog1
            .AssertReply("BeginDialog test3:subDialog.lg")
            .Send("turn4")
            .AssertReply("ContinueDialog test3:subDialog.lg")
            .AssertReply("Done")
            .StartTestAsync();
        }
Exemplo n.º 26
0
        public RootDialog(IConfiguration configuration)
            : base(nameof(RootDialog))
        {
            Configuration = configuration;
            // Create instance of adaptive dialog.
            var rootDialog = new AdaptiveDialog(nameof(AdaptiveDialog))
            {
                // Create a LUIS recognizer.
                // The recognizer is built using the intents, utterances, patterns and entities defined in ./RootDialog.lu file
                Recognizer = CreateRecognizer(),
                Rules      = new List <IRule>()
                {
                    // Intent rules for the LUIS model. Each intent here corresponds to an intent defined in ./Dialogs/Resources/ToDoBot.lu file
                    new IntentRule("Greeting")
                    {
                        Steps = new List <IDialog>()
                        {
                            new SendActivity("[Help-Root-Dialog]")
                        }
                    },
                    new IntentRule("AddToDoDialog")
                    {
                        Steps = new List <IDialog>()
                        {
                            new BeginDialog(nameof(AddToDoDialog))
                        }
                    },
                    new IntentRule("DeleteToDoDialog")
                    {
                        Steps = new List <IDialog>()
                        {
                            new BeginDialog(nameof(DeleteToDoDialog))
                        }
                    },
                    new IntentRule("ViewToDoDialog")
                    {
                        Steps = new List <IDialog>()
                        {
                            new BeginDialog(nameof(ViewToDoDialog))
                        }
                    },
                    // Come back with LG template based readback for global help
                    new IntentRule("Help")
                    {
                        Steps = new List <IDialog>()
                        {
                            new SendActivity("[Help-Root-Dialog]")
                        }
                    },
                    new IntentRule("Cancel")
                    {
                        Steps = new List <IDialog>()
                        {
                            // This is the global cancel in case a child dialog did not explicit handle cancel.
                            new SendActivity("Cancelling all dialogs.."),
                            // SendActivity supports full language generation resolution.
                            // See here to learn more about language generation
                            // https://github.com/Microsoft/BotBuilder-Samples/tree/master/experimental/language-generation
                            new SendActivity("[Welcome-Actions]"),
                            new CancelAllDialogs(),
                        }
                    }
                }
            };

            // Add named dialogs to the DialogSet. These names are saved in the dialog state.
            AddDialog(rootDialog);

            // Add all child dialogS
            AddDialog(new AddToDoDialog());
            AddDialog(new DeleteToDoDialog());
            AddDialog(new ViewToDoDialog());

            // The initial child Dialog to run.
            InitialDialogId = nameof(AdaptiveDialog);
        }
Exemplo n.º 27
0
        public DeleteToDoDialog(IConfiguration configuration)
            : base(nameof(DeleteToDoDialog))
        {
            string[] paths    = { ".", "Dialogs", "DeleteToDoDialog", "DeleteToDoDialog.lg" };
            string   fullPath = Path.Combine(paths);

            // Create instance of adaptive dialog.
            this._deleteToDoDialog = new AdaptiveDialog(nameof(DeleteToDoDialog))
            {
                Generator  = new TemplateEngineLanguageGenerator(Templates.ParseFile(fullPath)),
                Recognizer = CreateCrossTrainedRecognizer(configuration),
                Triggers   = new List <OnCondition>()
                {
                    new OnBeginDialog()
                    {
                        Actions = new List <Dialog>()
                        {
                            // Handle case where there are no items in todo list
                            new IfCondition()
                            {
                                // All conditions are expressed using adaptive expressions.
                                // See https://aka.ms/adaptive-expressions to learn more
                                Condition = "count(user.lists.todo) == 0 && count(user.lists.grocery) == 0 && count(user.lists.shopping) == 0",
                                Actions   = new List <Dialog>()
                                {
                                    new SendActivity("${DeleteEmptyList()}"),
                                    new EndDialog()
                                }
                            },

                            // User could have specified the item and/ or list type to delete.
                            new SetProperties()
                            {
                                Assignments = new List <PropertyAssignment>()
                                {
                                    new PropertyAssignment()
                                    {
                                        Property = "dialog.itemTitle",
                                        Value    = "=@itemTitle"
                                    },
                                    new PropertyAssignment()
                                    {
                                        Property = "dialog.listType",
                                        Value    = "=@listType"
                                    }
                                }
                            },

                            // Ask for list type first.
                            new TextInput()
                            {
                                Property           = "dialog.listType",
                                Prompt             = new ActivityTemplate("${GetListType()}"),
                                Value              = "=@listType",
                                AllowInterruptions = "!@listType && turn.recognized.score >= 0.7",
                                Validations        = new List <BoolExpression>()
                                {
                                    // Verify using expressions that the value is one of todo or shopping or grocery
                                    "contains(createArray('todo', 'shopping', 'grocery'), toLower(this.value))",
                                },
                                OutputFormat         = "=toLower(this.value)",
                                InvalidPrompt        = new ActivityTemplate("${GetListType.Invalid()}"),
                                MaxTurnCount         = 2,
                                DefaultValue         = "todo",
                                DefaultValueResponse = new ActivityTemplate("${GetListType.DefaultValueResponse()}")
                            },

                            new IfCondition()
                            {
                                Condition = "count(user.lists[dialog.listType]) == 0",
                                Actions   = new List <Dialog>()
                                {
                                    new SendActivity("${NoItemsInList()}"),
                                    new EndDialog()
                                }
                            },

                            // Ask for title to delete
                            new ChoiceInput()
                            {
                                Choices      = "user.lists[dialog.listType]",
                                Property     = "dialog.itemTitle",
                                OutputFormat = ChoiceOutputFormat.Value,
                                Style        = ListStyle.List,
                                Prompt       = new ActivityTemplate("${GetItemTitleToDelete()}")
                            },

                            // remove item
                            new EditArray()
                            {
                                ItemsProperty = "user.lists[dialog.listType]",
                                Value         = "=dialog.itemTitle",
                                ChangeType    = EditArray.ArrayChangeType.Remove
                            },

                            new SendActivity("${DeleteConfirmationReadBack()}")
                        }
                    },
                    // Shows how to use dialog event to capture intent recognition event for more than one intent.
                    // Alternate to this would be to add two separate OnIntent events.
                    // This ensures we set any entities recognized by these two intents.
                    new OnDialogEvent()
                    {
                        Event     = AdaptiveEvents.RecognizedIntent,
                        Condition = "#GetTitleToDelete || #GetListType",
                        Actions   = new List <Dialog>()
                        {
                            new SetProperties()
                            {
                                Assignments = new List <PropertyAssignment>()
                                {
                                    new PropertyAssignment()
                                    {
                                        Property = "dialog.itemTitle",
                                        Value    = "=@itemTitle"
                                    },
                                    new PropertyAssignment()
                                    {
                                        Property = "dialog.listType",
                                        Value    = "=@listType"
                                    }
                                }
                            }
                        }
                    },
                    // Help and chitchat is handled by qna
                    new OnQnAMatch
                    {
                        Actions = new List <Dialog>()
                        {
                            new CodeAction(ResolveAndSendQnAAnswer)
                        }
                    }
                }
            };

            // Add named dialogs to the DialogSet. These names are saved in the dialog state.
            AddDialog(this._deleteToDoDialog);

            // The initial child Dialog to run.
            InitialDialogId = nameof(DeleteToDoDialog);
        }
Exemplo n.º 28
0
        public async Task Action_HttpRequest()
        {
            var handler = new MockHttpMessageHandler();

            handler
            .When(HttpMethod.Post, "http://foo.com/")
            .WithContent("Joe is 52")
            .Respond("plain/text", "string");

            handler
            .When(HttpMethod.Post, "http://foo.com/")
            .WithContent("{\r\n  \"text\": \"Joe is 52\",\r\n  \"age\": 52\r\n}".Replace("\r\n", Environment.NewLine))
            .Respond("plain/text", "object");

            handler
            .When(HttpMethod.Post, "http://foo.com/")
            .WithHeaders(new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("bound", "52"),
                new KeyValuePair <string, string>("unbound", "dialog.age")
            })
            .WithContent("[\r\n  {\r\n    \"text\": \"Joe is 52\",\r\n    \"age\": 52\r\n  },\r\n  {\r\n    \"text\": \"text\",\r\n    \"age\": 11\r\n  }\r\n]".Replace("\r\n", Environment.NewLine))
            .Respond("plain/text", "array");

            // Reply with a bytes array and this bytes array would be base64encoded by the sdk
            handler
            .When(HttpMethod.Get, "http://foo.com/image")
            .Respond("image/jpeg", new MemoryStream(System.Text.Encoding.ASCII.GetBytes("TestImage")));

            handler
            .When(HttpMethod.Get, "http://foo.com/json")
            .Respond("application/json", "{\"test\": \"test\"}");

            var messageActivityWithText = Activity.CreateMessageActivity();

            messageActivityWithText.Text = "testtest";
            handler
            .When(HttpMethod.Get, "http://foo.com/activity")
            .Respond("application/vnd.microsoft.activity", JsonConvert.SerializeObject(messageActivityWithText));

            var message1 = Activity.CreateMessageActivity();

            message1.Text = "test1";

            var message2 = Activity.CreateMessageActivity();

            message2.Text = "test2";

            var message3 = Activity.CreateMessageActivity();

            message3.Text = "test3";

            var listOfActivites = new Activity[]
            {
                (Activity)message1,
                (Activity)message2,
                (Activity)message3
            };

            handler
            .When(HttpMethod.Get, "http://foo.com/activities")
            .Respond("application/vnd.microsoft.activities", JsonConvert.SerializeObject(listOfActivites));

            var testAdapter = new TestAdapter()
                              .UseStorage(new MemoryStorage())
                              .UseBotState(new ConversationState(new MemoryStorage()), new UserState(new MemoryStorage()));

            var rootDialog = new AdaptiveDialog()
            {
                Triggers = new List <Conditions.OnCondition>()
                {
                    new OnBeginDialog()
                    {
                        Actions = new List <Dialog>()
                        {
                            new SetProperties()
                            {
                                Assignments = new List <PropertyAssignment>()
                                {
                                    new PropertyAssignment()
                                    {
                                        Property = "dialog.name", Value = "Joe"
                                    },
                                    new PropertyAssignment()
                                    {
                                        Property = "dialog.age", Value = 52
                                    },
                                }
                            },
                            new HttpRequest()
                            {
                                Url         = "http://foo.com/",
                                Method      = HttpRequest.HttpMethod.POST,
                                ContentType = "plain/text",
                                Body        = "${dialog.name} is ${dialog.age}"
                            },
                            new SendActivity("${turn.lastresult.content}"),
                            new HttpRequest()
                            {
                                Url         = "http://foo.com/",
                                Method      = HttpRequest.HttpMethod.POST,
                                ContentType = "application/json",
                                Body        = JToken.FromObject(new
                                {
                                    text = "${dialog.name} is ${dialog.age}",
                                    age  = "=dialog.age"
                                })
                            },
                            new SendActivity("${turn.lastresult.content}"),
                            new HttpRequest()
                            {
                                Url         = "http://foo.com/",
                                Method      = HttpRequest.HttpMethod.POST,
                                ContentType = "application/json",
                                Headers     = new Dictionary <string, AdaptiveExpressions.Properties.StringExpression>()
                                {
                                    { "bound", "=dialog.age" },
                                    { "unbound", "dialog.age" }
                                },
                                Body = JToken.FromObject(new object[]
                                {
                                    new
                                    {
                                        text = "${dialog.name} is ${dialog.age}",
                                        age  = "=dialog.age"
                                    },
                                    new
                                    {
                                        text = "text",
                                        age  = 11
                                    }
                                })
                            },
                            new SendActivity("${turn.lastresult.content}"),
                            new HttpRequest()
                            {
                                Url          = "http://foo.com/image",
                                Method       = HttpRequest.HttpMethod.GET,
                                ResponseType = HttpRequest.ResponseTypes.Binary
                            },
                            new SendActivity("${turn.lastresult.content}"),
                            new HttpRequest()
                            {
                                Url          = "http://foo.com/json",
                                Method       = HttpRequest.HttpMethod.GET,
                                ResponseType = HttpRequest.ResponseTypes.Json
                            },
                            new SendActivity("${turn.lastresult.content.test}"),
                            new HttpRequest()
                            {
                                Url          = "http://foo.com/activity",
                                Method       = HttpRequest.HttpMethod.GET,
                                ResponseType = HttpRequest.ResponseTypes.Activity
                            },
                            new HttpRequest()
                            {
                                Url          = "http://foo.com/activities",
                                Method       = HttpRequest.HttpMethod.GET,
                                ResponseType = HttpRequest.ResponseTypes.Activities
                            },
                            new SendActivity("done")
                        }
                    }
                }
            };

            var dm = new DialogManager(rootDialog)
                     .UseResourceExplorer(new ResourceExplorer())
                     .UseLanguageGeneration();

            dm.InitialTurnState.Set <HttpClient>(handler.ToHttpClient());

            await new TestFlow((TestAdapter)testAdapter, dm.OnTurnAsync)
            .SendConversationUpdate()
            .AssertReply("string")
            .AssertReply("object")
            .AssertReply("array")
            .AssertReply("VGVzdEltYWdl")
            .AssertReply("test")
            .AssertReply("testtest")
            .AssertReply("test1")
            .AssertReply("test2")
            .AssertReply("test3")
            .AssertReply("done")
            .StartTestAsync();
        }
        private AdaptiveDialog CreateQnAMakerActionDialog(MockHttpMessageHandler mockHttp)
        {
            var client = new HttpClient(mockHttp);

            var rootDialog = new AdaptiveDialog("outer")
            {
                AutoEndDialog = false,
                Recognizer    = new QnAMakerRecognizer
                {
                    KnowledgeBaseId = KnowledgeBaseId,
                    HostName        = Hostname,
                    EndpointKey     = EndpointKey,
                    HttpClient      = client
                },
                Triggers = new List <OnCondition>
                {
                    new OnQnAMatch
                    {
                        Actions = new List <Dialog>
                        {
                            new SendActivity
                            {
                                Activity = new ActivityTemplate("${@answer}")
                            },
                            new AssertCondition
                            {
                                Condition   = "count(turn.recognized.entities.answer) == 1",
                                Description = "If there is a match there should only be 1 answer"
                            },
                            new AssertCondition
                            {
                                Condition   = "turn.recognized.entities.$instance.answer[0].startIndex == 0",
                                Description = "startIndex should be 0",
                            },
                            new AssertCondition
                            {
                                Condition   = "turn.recognized.entities.$instance.answer[0].endIndex != null",
                                Description = "endIndex should not be null",
                            },
                            new AssertCondition
                            {
                                Condition   = "turn.recognized.answers[0].answer != null",
                                Description = "There should be answers object"
                            },
                            new SendActivity
                            {
                                Activity = new ActivityTemplate("done")
                            }
                        }
                    },
                    new OnIntent
                    {
                        Intent  = "DeferToRecognizer_xxx",
                        Actions = new List <Dialog>
                        {
                            new SendActivity
                            {
                                Activity = new ActivityTemplate("DeferToRecognizer_xxx")
                            }
                        }
                    },
                    new OnUnknownIntent
                    {
                        Actions = new List <Dialog>
                        {
                            new SendActivity("Wha?")
                        }
                    }
                }
            };

            return(rootDialog);
        }
Exemplo n.º 30
0
        public RootDialog(IConfiguration configuration)
            : base(nameof(RootDialog))
        {
            Configuration = configuration;
            _lgEngine     = new TemplateEngine().AddFile(Path.Combine(".", "Dialogs", "RootDialog.lg"));

            // Create instance of adaptive dialog.
            var rootDialog = new AdaptiveDialog(nameof(AdaptiveDialog))
            {
                // There are no steps associated with this dialog.
                // This dialog will react to user input using its own Recognizer's output and Rules.

                // Add a recognizer to this adaptive dialog.
                // For this dialog, we will use the LUIS recognizer based on the FlightBooking.json
                // found under CognitiveModels folder.
                Recognizer = CreateRecognizer(configuration),
                // Add rules to respond to different events of interest
                //Rules = CreateRules()
                Generator = new TemplateEngineLanguageGenerator(_lgEngine),
                Triggers  = new List <OnCondition>()
                {
                    // Add a rule to welcome user
                    new OnConversationUpdateActivity()
                    {
                        Actions = WelcomeUserSteps()
                    },
                    // Add additional rules to respond to other intents returned by the LUIS application.
                    // The intents here are based on intents defined in MainAdaptiveDialog.LU file
                    new OnIntent()
                    {
                        Intent    = "Cancel",
                        Condition = "#Cancel.Score >= 0.8",
                        Actions   = new List <Dialog>()
                        {
                            new SendActivity("Sure, cancelling that..."),
                            new CancelAllDialogs(),
                            new EndDialog()
                        }
                    },
                    new OnIntent()
                    {
                        Intent    = "Help",
                        Condition = "#Help.Score >= 0.8",
                        Actions   = new List <Dialog> ()
                        {
                            new SendActivity("@{BotOverview()}")
                        }
                    },
                    new OnIntent()
                    {
                        Intent  = "Greeting",
                        Actions = new List <Dialog> ()
                        {
                            new SendActivity("@{BotOverview()}")
                        }
                    },
                    new OnUnknownIntent()
                    {
                        Actions = new List <Dialog>()
                        {
                            new SendActivity("@{UnknownIntent()}")
                        }
                    },
                    new OnIntent("Book_flight")
                    {
                        Actions = new List <Dialog>()
                        {
                            // Save any entities returned by LUIS.
                            // We will only save any geography city entities that explicitly have been classified as either fromCity or toCity.
                            new SetProperty()
                            {
                                Property = "conversation.flightBooking.departureCity",
                                // Value is an expresson. @entityName is short hand to refer to the value of an entity recognized.
                                // @xxx is same as turn.recognized.entities.xxx
                                Value = "@fromCity.location"
                            },
                            new SetProperty()
                            {
                                Property = "conversation.flightBooking.destinationCity",
                                Value    = "@toCity.location"
                            },
                            new SetProperty()
                            {
                                Property = "conversation.flightBooking.departureDate",
                                Value    = "@datetime.timex[0]"
                            },
                            // Steps to book flight
                            // Help and Cancel intents are always available since TextInput will always initiate
                            // Consulatation up the parent dialog chain to see if anyone else wants to take the user input.
                            new TextInput()
                            {
                                Property = "conversation.flightBooking.departureCity",
                                // Prompt property supports full language generation resolution.
                                // See here to learn more about language generation
                                // https://github.com/Microsoft/BotBuilder-Samples/tree/master/experimental/language-generation
                                Prompt = new ActivityTemplate("@{PromptForMissingInformation()}"),
                                // We will allow interruptions as long as the user did not explicitly answer the question
                                // This property supports an expression so you can examine presence of an intent via #intentName,
                                //    detect presence of an entity via @entityName etc. Interruption is allowed if the expression
                                //    evaluates to `true`. This property defaults to `true`.
                                AllowInterruptions = "!@fromCity || !@geographyV2",
                                // Value is an expression. Take any recognized city name as fromCity
                                Value = "@geographyV2.location"
                            },
                            new TextInput()
                            {
                                Property           = "conversation.flightBooking.destinationCity",
                                Prompt             = new ActivityTemplate("@{PromptForMissingInformation()}"),
                                AllowInterruptions = "!@toCity || !@geographyV2",
                                // Value is an expression. Take any recognized city name as fromCity
                                Value = "@geographyV2.location"
                            },
                            new DateTimeInput()
                            {
                                Property           = "conversation.flightBooking.departureDate",
                                Prompt             = new ActivityTemplate("@{PromptForMissingInformation()}"),
                                AllowInterruptions = "!@datetime",
                                // Value is an expression. Take any date time entity recognition as deparature date.
                                Value = "@datetime.timex[0]"
                            },
                            new ConfirmInput()
                            {
                                Property = "turn.bookingConfirmation",
                                Prompt   = new ActivityTemplate("@{ConfirmBooking()}"),
                                // You can use this flag to control when a specific input participates in consultation bubbling and can be interrupted.
                                // 'false' means intteruption is not allowed when this input is active.
                                AllowInterruptions = "false"
                            },
                            new IfCondition()
                            {
                                // All conditions are expressed using the common expression language.
                                // See https://github.com/Microsoft/BotBuilder-Samples/tree/master/experimental/common-expression-language to learn more
                                Condition = "turn.bookingConfirmation == true",
                                Actions   = new List <Dialog>()
                                {
                                    // TODO: book flight.
                                    new SendActivity("@{BookingConfirmation()}")
                                },
                                ElseActions = new List <Dialog>()
                                {
                                    new SendActivity("Thank you.")
                                }
                            }
                        }
                    }
                }
            };

            // Add named dialogs to the DialogSet. These names are saved in the dialog state.
            AddDialog(rootDialog);

            // The initial child Dialog to run.
            InitialDialogId = nameof(AdaptiveDialog);
        }