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); } }
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."); }
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); }
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"]); }
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); }
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); }
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(); }
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); }
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."); }
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(); }
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); }
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(); }
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); }
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); }
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); }
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")); }
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(); }
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 })); }
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(); }
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 })); }
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(); }
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); }
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); }
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); }
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); }