Multi-turn prompt: Summarizing the collected information before asking to confirm if collected info is Ok. (#3957)

* Multi-turn prompt: Summarizing the collected information before asking to confirm if collected info is Ok.

* Fixing lint errors
This commit is contained in:
gandiddi 2024-04-08 20:46:54 +05:30 коммит произвёл GitHub
Родитель 93bf76460a
Коммит 9fd77a1747
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 118 добавлений и 105 удалений

Просмотреть файл

@ -30,8 +30,8 @@ namespace Microsoft.BotBuilderSamples
NameConfirmStepAsync,
AgeStepAsync,
PictureStepAsync,
ConfirmStepAsync,
SummaryStepAsync,
ConfirmStepAsync,
};
// Add named dialogs to the DialogSet. These names are saved in the dialog state.
@ -127,54 +127,60 @@ namespace Microsoft.BotBuilderSamples
private async Task<DialogTurnResult> ConfirmStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values["picture"] = ((IList<Attachment>)stepContext.Result)?.FirstOrDefault();
var msg = $"Thanks. ";
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is a Prompt Dialog.
return await stepContext.PromptAsync(nameof(ConfirmPrompt), new PromptOptions { Prompt = MessageFactory.Text("Is this ok?") }, cancellationToken);
if ((bool)stepContext.Result)
{
msg += $" Your profile saved successfully.";
}
else
{
msg += $" Your profile will not be kept.";
}
await stepContext.Context.SendActivityAsync(MessageFactory.Text(msg), cancellationToken);
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is the end.
return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
}
private async Task<DialogTurnResult> SummaryStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
if ((bool)stepContext.Result)
stepContext.Values["picture"] = ((IList<Attachment>)stepContext.Result)?.FirstOrDefault();
// Get the current profile object from user state.
var userProfile = await _userProfileAccessor.GetAsync(stepContext.Context, () => new UserProfile(), cancellationToken);
userProfile.Transport = (string)stepContext.Values["transport"];
userProfile.Name = (string)stepContext.Values["name"];
userProfile.Age = (int)stepContext.Values["age"];
userProfile.Picture = (Attachment)stepContext.Values["picture"];
var msg = $"I have your mode of transport as {userProfile.Transport} and your name as {userProfile.Name}";
if (userProfile.Age != -1)
{
// Get the current profile object from user state.
var userProfile = await _userProfileAccessor.GetAsync(stepContext.Context, () => new UserProfile(), cancellationToken);
userProfile.Transport = (string)stepContext.Values["transport"];
userProfile.Name = (string)stepContext.Values["name"];
userProfile.Age = (int)stepContext.Values["age"];
userProfile.Picture = (Attachment)stepContext.Values["picture"];
var msg = $"I have your mode of transport as {userProfile.Transport} and your name as {userProfile.Name}";
if (userProfile.Age != -1)
{
msg += $" and your age as {userProfile.Age}";
}
msg += ".";
await stepContext.Context.SendActivityAsync(MessageFactory.Text(msg), cancellationToken);
if (userProfile.Picture != null)
{
try
{
await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(userProfile.Picture, "This is your profile picture."), cancellationToken);
}
catch
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text("A profile picture was saved but could not be displayed here."), cancellationToken);
}
}
}
else
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text("Thanks. Your profile will not be kept."), cancellationToken);
msg += $" and your age as {userProfile.Age}";
}
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is the end.
return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
msg += ".";
await stepContext.Context.SendActivityAsync(MessageFactory.Text(msg), cancellationToken);
if (userProfile.Picture != null)
{
try
{
await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(userProfile.Picture, "This is your profile picture."), cancellationToken);
}
catch
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text("A profile picture was saved but could not be displayed here."), cancellationToken);
}
}
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is a Prompt Dialog.
return await stepContext.PromptAsync(nameof(ConfirmPrompt), new PromptOptions { Prompt = MessageFactory.Text("Is this ok?") }, cancellationToken);
}
private static Task<bool> AgePromptValidatorAsync(PromptValidatorContext<int> promptContext, CancellationToken cancellationToken)

Просмотреть файл

@ -43,8 +43,8 @@ class UserProfileDialog extends ComponentDialog {
this.nameConfirmStep.bind(this),
this.ageStep.bind(this),
this.pictureStep.bind(this),
this.confirmStep.bind(this),
this.summaryStep.bind(this)
this.summaryStep.bind(this),
this.confirmStep.bind(this)
]));
this.initialDialogId = WATERFALL_DIALOG;
@ -128,42 +128,47 @@ class UserProfileDialog extends ComponentDialog {
}
async confirmStep(step) {
step.values.picture = step.result && step.result[0];
let msg = 'Thanks.';
if (step.result) {
msg += ' Your profile saved successfully.';
} else {
msg += ' Your profile will not be kept.';
}
await step.context.sendActivity(msg);
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is a Prompt Dialog.
return await step.prompt(CONFIRM_PROMPT, { prompt: 'Is this okay?' });
return await step.endDialog();
}
async summaryStep(step) {
if (step.result) {
// Get the current profile object from user state.
const userProfile = await this.userProfile.get(step.context, new UserProfile());
step.values.picture = step.result && step.result[0];
userProfile.transport = step.values.transport;
userProfile.name = step.values.name;
userProfile.age = step.values.age;
userProfile.picture = step.values.picture;
// Get the current profile object from user state.
const userProfile = await this.userProfile.get(step.context, new UserProfile());
let msg = `I have your mode of transport as ${ userProfile.transport } and your name as ${ userProfile.name }`;
if (userProfile.age !== -1) {
msg += ` and your age as ${ userProfile.age }`;
userProfile.transport = step.values.transport;
userProfile.name = step.values.name;
userProfile.age = step.values.age;
userProfile.picture = step.values.picture;
let msg = `I have your mode of transport as ${ userProfile.transport } and your name as ${ userProfile.name }`;
if (userProfile.age !== -1) {
msg += ` and your age as ${ userProfile.age }`;
}
msg += '.';
await step.context.sendActivity(msg);
if (userProfile.picture) {
try {
await step.context.sendActivity(MessageFactory.attachment(userProfile.picture, 'This is your profile picture.'));
} catch {
await step.context.sendActivity('A profile picture was saved but could not be displayed here.');
}
msg += '.';
await step.context.sendActivity(msg);
if (userProfile.picture) {
try {
await step.context.sendActivity(MessageFactory.attachment(userProfile.picture, 'This is your profile picture.'));
} catch {
await step.context.sendActivity('A profile picture was saved but could not be displayed here.');
}
}
} else {
await step.context.sendActivity('Thanks. Your profile will not be kept.');
}
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is the end.
return await step.endDialog();
return await step.prompt(CONFIRM_PROMPT, { prompt: 'Is this okay?' });
}
async agePromptValidator(promptContext) {

Просмотреть файл

@ -37,8 +37,8 @@ class UserProfileDialog(ComponentDialog):
self.name_confirm_step,
self.age_step,
self.picture_step,
self.confirm_step,
self.summary_step,
self.confirm_step,
],
)
)
@ -152,56 +152,58 @@ class UserProfileDialog(ComponentDialog):
async def confirm_step(
self, step_context: WaterfallStepContext
) -> DialogTurnResult:
step_context.values["picture"] = (
None if not step_context.result else step_context.result[0]
)
msg = f"Thanks."
if step_context.result:
msg += f" Your profile saved successfully."
else:
msg += f" Your profile will not be kept."
await step_context.context.send_activity(MessageFactory.text(msg))
# WaterfallStep always finishes with the end of the Waterfall or
# with another dialog; here it is a Prompt Dialog.
return await step_context.prompt(
ConfirmPrompt.__name__,
PromptOptions(prompt=MessageFactory.text("Is this ok?")),
)
return await step_context.end_dialog()
async def summary_step(
self, step_context: WaterfallStepContext
) -> DialogTurnResult:
if step_context.result:
# Get the current profile object from user state. Changes to it
# will saved during Bot.on_turn.
user_profile = await self.user_profile_accessor.get(
step_context.context, UserProfile
step_context.values["picture"] = (
None if not step_context.result else step_context.result[0]
)
# Get the current profile object from user state. Changes to it
# will saved during Bot.on_turn.
user_profile = await self.user_profile_accessor.get(
step_context.context, UserProfile
)
user_profile.transport = step_context.values["transport"]
user_profile.name = step_context.values["name"]
user_profile.age = step_context.values["age"]
user_profile.picture = step_context.values["picture"]
msg = f"I have your mode of transport as {user_profile.transport} and your name as {user_profile.name}."
if user_profile.age != -1:
msg += f" And age as {user_profile.age}."
await step_context.context.send_activity(MessageFactory.text(msg))
if user_profile.picture:
await step_context.context.send_activity(
MessageFactory.attachment(
user_profile.picture, "This is your profile picture."
)
)
user_profile.transport = step_context.values["transport"]
user_profile.name = step_context.values["name"]
user_profile.age = step_context.values["age"]
user_profile.picture = step_context.values["picture"]
msg = f"I have your mode of transport as {user_profile.transport} and your name as {user_profile.name}."
if user_profile.age != -1:
msg += f" And age as {user_profile.age}."
await step_context.context.send_activity(MessageFactory.text(msg))
if user_profile.picture:
await step_context.context.send_activity(
MessageFactory.attachment(
user_profile.picture, "This is your profile picture."
)
)
else:
await step_context.context.send_activity(
"A profile picture was saved but could not be displayed here."
)
else:
await step_context.context.send_activity(
MessageFactory.text("Thanks. Your profile will not be kept.")
"A profile picture was saved but could not be displayed here."
)
# WaterfallStep always finishes with the end of the Waterfall or with another
# dialog, here it is the end.
return await step_context.end_dialog()
return await step_context.prompt(
ConfirmPrompt.__name__,
PromptOptions(prompt=MessageFactory.text("Is this ok?")),
)
@staticmethod
async def age_prompt_validator(prompt_context: PromptValidatorContext) -> bool: