Sequential Waterfall Models with Complex Dialog flows Bot Framework C# v4
I have 3 Independent waterfall models which are triggered by intents using Luis.
I want to link these 3 models sequentially, I have been following the PictureBot coding style, and each dialog/waterfall has it's on state properties.
The 3 Waterfall Methods are as follows,
- WaterFall_1 - Query Azure Search, based on filters provided by the user, the Response is a list of Names
- WaterFall_2 - Will perform some REST action, taking the names from waterFall_1
- WaterFall_3 - Will again perform some REST action, taking the names from WaterFall_1
As of now, I have been passing the values through the chat-window, as the 3 Waterfall steps are loosely coupled, they can be called by the user as an independent component/feature of the bot, so my questions are
How do link the 3 Models, ie in If the user has triggered waterfall_1, and goes to 2 or 3, the dialog where the "Users" are asked is to be skipped? I am thinking that I would need both a Global and Local Getters and Setters for each Waterfall.
In the WaterFall_1, the last response sends the Query Result from Azure Search, ie the "Names", Should I endDialog right after or does the WaterFall_1 call the WaterFall_2 and/if WaterFall_3 and then I endDialog for 3,2,1?
The figure might give more context Simple figure
c# botframework
add a comment |
I have 3 Independent waterfall models which are triggered by intents using Luis.
I want to link these 3 models sequentially, I have been following the PictureBot coding style, and each dialog/waterfall has it's on state properties.
The 3 Waterfall Methods are as follows,
- WaterFall_1 - Query Azure Search, based on filters provided by the user, the Response is a list of Names
- WaterFall_2 - Will perform some REST action, taking the names from waterFall_1
- WaterFall_3 - Will again perform some REST action, taking the names from WaterFall_1
As of now, I have been passing the values through the chat-window, as the 3 Waterfall steps are loosely coupled, they can be called by the user as an independent component/feature of the bot, so my questions are
How do link the 3 Models, ie in If the user has triggered waterfall_1, and goes to 2 or 3, the dialog where the "Users" are asked is to be skipped? I am thinking that I would need both a Global and Local Getters and Setters for each Waterfall.
In the WaterFall_1, the last response sends the Query Result from Azure Search, ie the "Names", Should I endDialog right after or does the WaterFall_1 call the WaterFall_2 and/if WaterFall_3 and then I endDialog for 3,2,1?
The figure might give more context Simple figure
c# botframework
add a comment |
I have 3 Independent waterfall models which are triggered by intents using Luis.
I want to link these 3 models sequentially, I have been following the PictureBot coding style, and each dialog/waterfall has it's on state properties.
The 3 Waterfall Methods are as follows,
- WaterFall_1 - Query Azure Search, based on filters provided by the user, the Response is a list of Names
- WaterFall_2 - Will perform some REST action, taking the names from waterFall_1
- WaterFall_3 - Will again perform some REST action, taking the names from WaterFall_1
As of now, I have been passing the values through the chat-window, as the 3 Waterfall steps are loosely coupled, they can be called by the user as an independent component/feature of the bot, so my questions are
How do link the 3 Models, ie in If the user has triggered waterfall_1, and goes to 2 or 3, the dialog where the "Users" are asked is to be skipped? I am thinking that I would need both a Global and Local Getters and Setters for each Waterfall.
In the WaterFall_1, the last response sends the Query Result from Azure Search, ie the "Names", Should I endDialog right after or does the WaterFall_1 call the WaterFall_2 and/if WaterFall_3 and then I endDialog for 3,2,1?
The figure might give more context Simple figure
c# botframework
I have 3 Independent waterfall models which are triggered by intents using Luis.
I want to link these 3 models sequentially, I have been following the PictureBot coding style, and each dialog/waterfall has it's on state properties.
The 3 Waterfall Methods are as follows,
- WaterFall_1 - Query Azure Search, based on filters provided by the user, the Response is a list of Names
- WaterFall_2 - Will perform some REST action, taking the names from waterFall_1
- WaterFall_3 - Will again perform some REST action, taking the names from WaterFall_1
As of now, I have been passing the values through the chat-window, as the 3 Waterfall steps are loosely coupled, they can be called by the user as an independent component/feature of the bot, so my questions are
How do link the 3 Models, ie in If the user has triggered waterfall_1, and goes to 2 or 3, the dialog where the "Users" are asked is to be skipped? I am thinking that I would need both a Global and Local Getters and Setters for each Waterfall.
In the WaterFall_1, the last response sends the Query Result from Azure Search, ie the "Names", Should I endDialog right after or does the WaterFall_1 call the WaterFall_2 and/if WaterFall_3 and then I endDialog for 3,2,1?
The figure might give more context Simple figure
c# botframework
c# botframework
edited Nov 18 '18 at 14:27
Aditya Rao
asked Nov 18 '18 at 14:21
Aditya RaoAditya Rao
185
185
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
You have the general idea down, in your question 1. What you would need is a 'shared' or global state not unlike the state demonstrated in the Bot Framework's CafeBot (Look under samples => dotnet => #50).
If you have a 'global' state set, you could save the list of user names retrieved in your Waterfall 1 to that. Then, when your second or third waterfall are called via your LUIS intents, you pass in the state accessor to the Waterfall 1 results to the parent class of Waterfall 2, thus making them accessible to the other waterfalls.
You would not need to make them sequential, if you're relying on LUIS. You could use LUIS to have 'Search Users' trigger WF1, 'Do XYZ to Users' trigger 2, and 'Do ABC to Users' trigger 3. This would make your bot less rigid for your bot users, as they could do a search, then do either 2 OR 3, (or both) as needed.
I was able to simulate this by simply adding an extra, waterfall based class to the Bot Framework MessageRoutingBot (samples => dotnet => #09)
Here is the waterfall setup for the 'Favorite Animal' prompt, including accessing the greetingState from the original sample bot:
public TestDialog(IStatePropertyAccessor<TestState> testStateAccessor, IStatePropertyAccessor<GreetingState> greetingStateAccessor, ILoggerFactory loggerFactory)
: base(nameof(TestDialog))
{
TestStateAccessor = testStateAccessor ?? throw new ArgumentNullException(nameof(testStateAccessor));
GreetingStateAccessor = greetingStateAccessor ?? throw new ArgumentNullException(nameof(greetingStateAccessor));
// Add control flow dialogs
var waterfallSteps = new WaterfallStep
{
InitializeStateStepAsync,
PromptForAnimalStepAsync,
// PromptForCityStepAsync,
DisplayTestStateStepAsync,
};
AddDialog(new WaterfallDialog(ProfileDialog, waterfallSteps));
// AddDialog(new TextPrompt(NamePrompt, ValidateName));
AddDialog(new TextPrompt(AnimalPrompt));
}
With the greetingState accessor pulled in, it allowed me to continue to call my user by name, from a second waterfall, without needing to reprompt for it:
private async Task<DialogTurnResult> GreetUser(WaterfallStepContext stepContext)
{
var context = stepContext.Context;
var testState = await TestStateAccessor.GetAsync(context);
var greetingState = await GreetingStateAccessor.GetAsync(context);
// Display their profile information and end dialog.
await context.SendActivityAsync($"Hi {greetingState.Name}, who likes {testState.Animal}s, nice to meet you!");
return await stepContext.EndDialogAsync();
}
Hope this helps!
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53361886%2fsequential-waterfall-models-with-complex-dialog-flows-bot-framework-c-sharp-v4%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You have the general idea down, in your question 1. What you would need is a 'shared' or global state not unlike the state demonstrated in the Bot Framework's CafeBot (Look under samples => dotnet => #50).
If you have a 'global' state set, you could save the list of user names retrieved in your Waterfall 1 to that. Then, when your second or third waterfall are called via your LUIS intents, you pass in the state accessor to the Waterfall 1 results to the parent class of Waterfall 2, thus making them accessible to the other waterfalls.
You would not need to make them sequential, if you're relying on LUIS. You could use LUIS to have 'Search Users' trigger WF1, 'Do XYZ to Users' trigger 2, and 'Do ABC to Users' trigger 3. This would make your bot less rigid for your bot users, as they could do a search, then do either 2 OR 3, (or both) as needed.
I was able to simulate this by simply adding an extra, waterfall based class to the Bot Framework MessageRoutingBot (samples => dotnet => #09)
Here is the waterfall setup for the 'Favorite Animal' prompt, including accessing the greetingState from the original sample bot:
public TestDialog(IStatePropertyAccessor<TestState> testStateAccessor, IStatePropertyAccessor<GreetingState> greetingStateAccessor, ILoggerFactory loggerFactory)
: base(nameof(TestDialog))
{
TestStateAccessor = testStateAccessor ?? throw new ArgumentNullException(nameof(testStateAccessor));
GreetingStateAccessor = greetingStateAccessor ?? throw new ArgumentNullException(nameof(greetingStateAccessor));
// Add control flow dialogs
var waterfallSteps = new WaterfallStep
{
InitializeStateStepAsync,
PromptForAnimalStepAsync,
// PromptForCityStepAsync,
DisplayTestStateStepAsync,
};
AddDialog(new WaterfallDialog(ProfileDialog, waterfallSteps));
// AddDialog(new TextPrompt(NamePrompt, ValidateName));
AddDialog(new TextPrompt(AnimalPrompt));
}
With the greetingState accessor pulled in, it allowed me to continue to call my user by name, from a second waterfall, without needing to reprompt for it:
private async Task<DialogTurnResult> GreetUser(WaterfallStepContext stepContext)
{
var context = stepContext.Context;
var testState = await TestStateAccessor.GetAsync(context);
var greetingState = await GreetingStateAccessor.GetAsync(context);
// Display their profile information and end dialog.
await context.SendActivityAsync($"Hi {greetingState.Name}, who likes {testState.Animal}s, nice to meet you!");
return await stepContext.EndDialogAsync();
}
Hope this helps!
add a comment |
You have the general idea down, in your question 1. What you would need is a 'shared' or global state not unlike the state demonstrated in the Bot Framework's CafeBot (Look under samples => dotnet => #50).
If you have a 'global' state set, you could save the list of user names retrieved in your Waterfall 1 to that. Then, when your second or third waterfall are called via your LUIS intents, you pass in the state accessor to the Waterfall 1 results to the parent class of Waterfall 2, thus making them accessible to the other waterfalls.
You would not need to make them sequential, if you're relying on LUIS. You could use LUIS to have 'Search Users' trigger WF1, 'Do XYZ to Users' trigger 2, and 'Do ABC to Users' trigger 3. This would make your bot less rigid for your bot users, as they could do a search, then do either 2 OR 3, (or both) as needed.
I was able to simulate this by simply adding an extra, waterfall based class to the Bot Framework MessageRoutingBot (samples => dotnet => #09)
Here is the waterfall setup for the 'Favorite Animal' prompt, including accessing the greetingState from the original sample bot:
public TestDialog(IStatePropertyAccessor<TestState> testStateAccessor, IStatePropertyAccessor<GreetingState> greetingStateAccessor, ILoggerFactory loggerFactory)
: base(nameof(TestDialog))
{
TestStateAccessor = testStateAccessor ?? throw new ArgumentNullException(nameof(testStateAccessor));
GreetingStateAccessor = greetingStateAccessor ?? throw new ArgumentNullException(nameof(greetingStateAccessor));
// Add control flow dialogs
var waterfallSteps = new WaterfallStep
{
InitializeStateStepAsync,
PromptForAnimalStepAsync,
// PromptForCityStepAsync,
DisplayTestStateStepAsync,
};
AddDialog(new WaterfallDialog(ProfileDialog, waterfallSteps));
// AddDialog(new TextPrompt(NamePrompt, ValidateName));
AddDialog(new TextPrompt(AnimalPrompt));
}
With the greetingState accessor pulled in, it allowed me to continue to call my user by name, from a second waterfall, without needing to reprompt for it:
private async Task<DialogTurnResult> GreetUser(WaterfallStepContext stepContext)
{
var context = stepContext.Context;
var testState = await TestStateAccessor.GetAsync(context);
var greetingState = await GreetingStateAccessor.GetAsync(context);
// Display their profile information and end dialog.
await context.SendActivityAsync($"Hi {greetingState.Name}, who likes {testState.Animal}s, nice to meet you!");
return await stepContext.EndDialogAsync();
}
Hope this helps!
add a comment |
You have the general idea down, in your question 1. What you would need is a 'shared' or global state not unlike the state demonstrated in the Bot Framework's CafeBot (Look under samples => dotnet => #50).
If you have a 'global' state set, you could save the list of user names retrieved in your Waterfall 1 to that. Then, when your second or third waterfall are called via your LUIS intents, you pass in the state accessor to the Waterfall 1 results to the parent class of Waterfall 2, thus making them accessible to the other waterfalls.
You would not need to make them sequential, if you're relying on LUIS. You could use LUIS to have 'Search Users' trigger WF1, 'Do XYZ to Users' trigger 2, and 'Do ABC to Users' trigger 3. This would make your bot less rigid for your bot users, as they could do a search, then do either 2 OR 3, (or both) as needed.
I was able to simulate this by simply adding an extra, waterfall based class to the Bot Framework MessageRoutingBot (samples => dotnet => #09)
Here is the waterfall setup for the 'Favorite Animal' prompt, including accessing the greetingState from the original sample bot:
public TestDialog(IStatePropertyAccessor<TestState> testStateAccessor, IStatePropertyAccessor<GreetingState> greetingStateAccessor, ILoggerFactory loggerFactory)
: base(nameof(TestDialog))
{
TestStateAccessor = testStateAccessor ?? throw new ArgumentNullException(nameof(testStateAccessor));
GreetingStateAccessor = greetingStateAccessor ?? throw new ArgumentNullException(nameof(greetingStateAccessor));
// Add control flow dialogs
var waterfallSteps = new WaterfallStep
{
InitializeStateStepAsync,
PromptForAnimalStepAsync,
// PromptForCityStepAsync,
DisplayTestStateStepAsync,
};
AddDialog(new WaterfallDialog(ProfileDialog, waterfallSteps));
// AddDialog(new TextPrompt(NamePrompt, ValidateName));
AddDialog(new TextPrompt(AnimalPrompt));
}
With the greetingState accessor pulled in, it allowed me to continue to call my user by name, from a second waterfall, without needing to reprompt for it:
private async Task<DialogTurnResult> GreetUser(WaterfallStepContext stepContext)
{
var context = stepContext.Context;
var testState = await TestStateAccessor.GetAsync(context);
var greetingState = await GreetingStateAccessor.GetAsync(context);
// Display their profile information and end dialog.
await context.SendActivityAsync($"Hi {greetingState.Name}, who likes {testState.Animal}s, nice to meet you!");
return await stepContext.EndDialogAsync();
}
Hope this helps!
You have the general idea down, in your question 1. What you would need is a 'shared' or global state not unlike the state demonstrated in the Bot Framework's CafeBot (Look under samples => dotnet => #50).
If you have a 'global' state set, you could save the list of user names retrieved in your Waterfall 1 to that. Then, when your second or third waterfall are called via your LUIS intents, you pass in the state accessor to the Waterfall 1 results to the parent class of Waterfall 2, thus making them accessible to the other waterfalls.
You would not need to make them sequential, if you're relying on LUIS. You could use LUIS to have 'Search Users' trigger WF1, 'Do XYZ to Users' trigger 2, and 'Do ABC to Users' trigger 3. This would make your bot less rigid for your bot users, as they could do a search, then do either 2 OR 3, (or both) as needed.
I was able to simulate this by simply adding an extra, waterfall based class to the Bot Framework MessageRoutingBot (samples => dotnet => #09)
Here is the waterfall setup for the 'Favorite Animal' prompt, including accessing the greetingState from the original sample bot:
public TestDialog(IStatePropertyAccessor<TestState> testStateAccessor, IStatePropertyAccessor<GreetingState> greetingStateAccessor, ILoggerFactory loggerFactory)
: base(nameof(TestDialog))
{
TestStateAccessor = testStateAccessor ?? throw new ArgumentNullException(nameof(testStateAccessor));
GreetingStateAccessor = greetingStateAccessor ?? throw new ArgumentNullException(nameof(greetingStateAccessor));
// Add control flow dialogs
var waterfallSteps = new WaterfallStep
{
InitializeStateStepAsync,
PromptForAnimalStepAsync,
// PromptForCityStepAsync,
DisplayTestStateStepAsync,
};
AddDialog(new WaterfallDialog(ProfileDialog, waterfallSteps));
// AddDialog(new TextPrompt(NamePrompt, ValidateName));
AddDialog(new TextPrompt(AnimalPrompt));
}
With the greetingState accessor pulled in, it allowed me to continue to call my user by name, from a second waterfall, without needing to reprompt for it:
private async Task<DialogTurnResult> GreetUser(WaterfallStepContext stepContext)
{
var context = stepContext.Context;
var testState = await TestStateAccessor.GetAsync(context);
var greetingState = await GreetingStateAccessor.GetAsync(context);
// Display their profile information and end dialog.
await context.SendActivityAsync($"Hi {greetingState.Name}, who likes {testState.Animal}s, nice to meet you!");
return await stepContext.EndDialogAsync();
}
Hope this helps!
answered Nov 28 '18 at 22:40
JJ_WailesJJ_Wailes
635112
635112
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53361886%2fsequential-waterfall-models-with-complex-dialog-flows-bot-framework-c-sharp-v4%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown