/// <summary> /// Called when the dialog should re-prompt the user for input. /// </summary> /// <param name="turnContext">The context object for this turn.</param> /// <param name="instance">State information for this dialog.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> /// <seealso cref="OnRepromptDialogAsync(ITurnContext, DialogInstance, CancellationToken)"/> /// <seealso cref="DialogContext.RepromptDialogAsync(CancellationToken)"/> public override async Task RepromptDialogAsync(ITurnContext turnContext, DialogInstance instance, CancellationToken cancellationToken = default(CancellationToken)) { // Delegate to inner dialog. var innerDc = new DialogContext(_dialogs, turnContext, GetDialogState(instance)); await innerDc.RepromptDialogAsync(cancellationToken).ConfigureAwait(false); // Notify component await OnRepromptDialogAsync(turnContext, instance, cancellationToken).ConfigureAwait(false); }
private static async Task <DialogTurnResult> InnerRunAsync(ITurnContext turnContext, string dialogId, DialogContext dialogContext, CancellationToken cancellationToken) { // Handle EoC and Reprompt event from a parent bot (can be root bot to skill or skill to skill) if (IsFromParentToSkill(turnContext)) { // Handle remote cancellation request from parent. if (turnContext.Activity.Type == ActivityTypes.EndOfConversation) { if (!dialogContext.Stack.Any()) { // No dialogs to cancel, just return. return(new DialogTurnResult(DialogTurnStatus.Empty)); } var activeDialogContext = GetActiveDialogContext(dialogContext); // Send cancellation message to the top dialog in the stack to ensure all the parents are canceled in the right order. return(await activeDialogContext.CancelAllDialogsAsync(true, cancellationToken : cancellationToken).ConfigureAwait(false)); } // Handle a reprompt event sent from the parent. if (turnContext.Activity.Type == ActivityTypes.Event && turnContext.Activity.Name == DialogEvents.RepromptDialog) { if (!dialogContext.Stack.Any()) { // No dialogs to reprompt, just return. return(new DialogTurnResult(DialogTurnStatus.Empty)); } await dialogContext.RepromptDialogAsync(cancellationToken).ConfigureAwait(false); return(new DialogTurnResult(DialogTurnStatus.Waiting)); } } // Continue or start the dialog. var result = await dialogContext.ContinueDialogAsync(cancellationToken).ConfigureAwait(false); if (result.Status == DialogTurnStatus.Empty) { result = await dialogContext.BeginDialogAsync(dialogId, null, cancellationToken).ConfigureAwait(false); } await SendStateSnapshotTraceAsync(dialogContext, cancellationToken).ConfigureAwait(false); // Skills should send EoC when the dialog completes. if (result.Status == DialogTurnStatus.Complete || result.Status == DialogTurnStatus.Cancelled) { if (SendEoCToParent(turnContext)) { // Send End of conversation at the end. var code = result.Status == DialogTurnStatus.Complete ? EndOfConversationCodes.CompletedSuccessfully : EndOfConversationCodes.UserCancelled; var activity = new Activity(ActivityTypes.EndOfConversation) { Value = result.Result, Locale = turnContext.Activity.Locale, Code = code }; await turnContext.SendActivityAsync(activity, cancellationToken).ConfigureAwait(false); } } return(result); }