private async Task <DialogTurnResult> RunStepAsync(DialogContext dc, int index, DialogReason reason, object result, CancellationToken cancellationToken) { if (dc == null) { throw new ArgumentNullException(nameof(dc)); } if (index < _steps.Count) { // Update persisted step index var state = dc.ActiveDialog.State; state[StepIndex] = index; // Create step context var options = state[PersistedOptions]; var values = (IDictionary <string, object>)state[PersistedValues]; var stepContext = new WaterfallStepContext(this, dc, options, values, index, reason, result); // Execute step return(await OnStepAsync(stepContext, cancellationToken).ConfigureAwait(false)); } else { // End of waterfall so just return any result to parent return(await dc.EndDialogAsync(result).ConfigureAwait(false)); } }
/// <summary> /// Called when a child dialog on the parent's dialog stack completed this turn, returning /// control to this dialog component. /// </summary> /// <param name="outerDc">The <see cref="DialogContext"/> for the current turn of conversation.</param> /// <param name="reason">Reason why the dialog resumed.</param> /// <param name="result">Optional, value returned from the dialog that was called. The type /// of the value returned is dependent on the child 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> /// <remarks>If the task is successful, the result indicates whether this dialog is still /// active after this dialog turn has been processed. /// /// Generally, the child dialog was started with a call to /// <see cref="BeginDialogAsync(DialogContext, object, CancellationToken)"/> in the parent's /// context. However, if the /// <see cref="DialogContext.ReplaceDialogAsync(string, object, CancellationToken)"/> method /// is called, the logical child dialog may be different than the original. /// /// If this method is *not* overridden, the dialog automatically calls its /// <see cref="RepromptDialogAsync(ITurnContext, DialogInstance, CancellationToken)"/> when /// the user replies. /// </remarks> /// <seealso cref="RepromptDialogAsync(ITurnContext, DialogInstance, CancellationToken)"/> public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { if (result is CancellationToken) { throw new ArgumentException($"{nameof(result)} cannot be a cancellation token"); } await EnsureInitializedAsync(outerDc).ConfigureAwait(false); await this.CheckForVersionChangeAsync(outerDc).ConfigureAwait(false); // Containers are typically leaf nodes on the stack but the dev is free to push other dialogs // on top of the stack which will result in the container receiving an unexpected call to // dialogResume() when the pushed on dialog ends. // To avoid the container prematurely ending we need to implement this method and simply // ask our inner dialog stack to re-prompt. await RepromptDialogAsync(outerDc.Context, outerDc.ActiveDialog, cancellationToken).ConfigureAwait(false); return(Dialog.EndOfTurn); }
/// <summary> /// Called when the dialog is ending. /// </summary> /// <param name="context">The context object for this turn.</param> /// <param name="instance">State information associated with the inner dialog stack of this /// component dialog.</param> /// <param name="reason">Reason why the dialog ended.</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> /// <remarks>Override this method in a derived class to implement any additional logic that /// should happen at the component level, after all inner dialogs have been canceled.</remarks> /// <seealso cref="EndDialogAsync(ITurnContext, DialogInstance, DialogReason, CancellationToken)"/> protected virtual Task OnEndDialogAsync(ITurnContext context, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken)) { return(Task.CompletedTask); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default) { if (result is ActionScopeResult actionScopeResult) { return(await OnActionScopeResultAsync(dc, actionScopeResult, cancellationToken).ConfigureAwait(false)); } return(await OnNextActionAsync(dc, result, cancellationToken).ConfigureAwait(false)); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { if (this.ResultProperty != null) { dc.State.SetValue(this.ResultProperty.GetValue(dc.State), result); } // By default just end the current dialog and return result to parent. return(await dc.EndDialogAsync(result, cancellationToken).ConfigureAwait(false)); }
/// <summary> /// Called when a child dialog completed its turn, returning control to this dialog. /// </summary> /// <param name="dc">The dialog context for the current turn of the conversation.</param> /// <param name="reason">Reason why the dialog resumed.</param> /// <param name="result">Optional, value returned from the dialog that was called. The type /// of the value returned is dependent on the child 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> public override Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default) { LoadDialogOptions(dc.Context, dc.ActiveDialog); return(base.ResumeDialogAsync(dc, reason, result, cancellationToken)); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default) { dc.State.SetValue("$xyz", result); await dc.Context.SendActivityAsync(dc.State.GetValue <string>("$xyz")); return(await dc.EndDialogAsync(result)); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default) { outerDc.GetState().SetValue(this.Property, result); await outerDc.Context.SendActivityAsync($"Hello {result.ToString()}, nice to meet you!"); return(await outerDc.EndDialogAsync(result)); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = new CancellationToken()) { var exeProp = (string)dc.ActiveDialog.State[Property]; var value = GetStoredValue(dc.ActiveDialog); if (result is FoundChoice resultChoice) { value[exeProp] = resultChoice.Value; } else { value[exeProp] = result; } return(await ExecuteProperty(dc, cancellation : cancellationToken)); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { var prompt = result as ResetPasswordPrompt; var email = outerDc.Context.Activity.From.Id; int?passcode; using (var db = new ContosoHelpdeskContext()) { passcode = db.ResetPasswords.Where(r => r.EmailAddress == email).First().PassCode; } if (prompt.PassCode == passcode) { string temppwd = "TempPwd" + new Random().Next(0, 5000); await outerDc.PostAsync($"Your temp password is {temppwd}"); } return(new DialogTurnResult(DialogTurnStatus.Complete)); }
public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken)) { // Forward cancel to inner dialogs if (reason == DialogReason.CancelCalled) { var dialogState = (DialogState)instance.State[PersistedDialogState]; var innerDc = new DialogContext(_dialogs, turnContext, dialogState); await innerDc.CancelAllDialogsAsync(cancellationToken).ConfigureAwait(false); } await OnEndDialogAsync(turnContext, instance, reason, cancellationToken).ConfigureAwait(false); }
public virtual Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken)) { // No-op by default return(Task.CompletedTask); }
/// <summary> /// Method called when an instance of the dialog is being returned to from another /// dialog that was started by the current instance using `DialogSet.begin()`. /// If this method is NOT implemented then the dialog will be automatically ended with a call /// to `DialogSet.endDialogWithResult()`. Any result passed from the called dialog will be passed /// to the current dialogs parent. /// </summary> /// <param name="dc">The dialog context for the current turn of conversation.</param> /// <param name="reason">Reason why the dialog resumed.</param> /// <param name="result">(Optional) value returned from the dialog that was called. The type of the value returned is dependant on the dialog that was called.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public virtual async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { // By default just end the current dialog and return result to parent. return(await dc.EndDialogAsync(result, cancellationToken).ConfigureAwait(false)); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result, CancellationToken cancellationToken = default(CancellationToken)) { if (dc == null) { throw new ArgumentNullException(nameof(dc)); } // Increment step index and run step var state = dc.ActiveDialog.State; // For issue https://github.com/Microsoft/botbuilder-dotnet/issues/871 // See the linked issue for details. This issue was happening when using the CosmosDB // data store for state. The stepIndex which was an object being cast to an Int64 // after deserialization was throwing an exception for not being Int32 datatype. // This change ensures the correct datatype conversion has been done. var index = Convert.ToInt32(state[StepIndex]); return(await RunStepAsync(dc, index + 1, reason, result, cancellationToken).ConfigureAwait(false)); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default) { await RepromptDialogAsync(dc.Context, dc.ActiveDialog, cancellationToken).ConfigureAwait(false); return(EndOfTurn); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default) { outerDc.State.SetValue(_property, result); await outerDc.Context.SendActivityAsync($"Hello {result}, nice to meet you!", cancellationToken : cancellationToken); return(await outerDc.EndDialogAsync(result, cancellationToken)); }
public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default) { // Send of of conversation to the skill if the dialog has been cancelled. if (reason == DialogReason.CancelCalled || reason == DialogReason.ReplaceCalled) { await turnContext.TraceActivityAsync($"{GetType().Name}.EndDialogAsync()", label : $"ActivityType: {turnContext.Activity.Type}", cancellationToken : cancellationToken).ConfigureAwait(false); var activity = (Activity)Activity.CreateEndOfConversationActivity(); // Apply conversation reference and common properties from incoming activity before sending. activity.ApplyConversationReference(turnContext.Activity.GetConversationReference(), true); activity.ChannelData = turnContext.Activity.ChannelData; activity.Properties = turnContext.Activity.Properties; // connection Name is not applicable for an EndDialog, as we don't expect as OAuthCard in response. await SendToSkillAsync(turnContext, activity, cancellationToken).ConfigureAwait(false); } await base.EndDialogAsync(turnContext, instance, reason, cancellationToken).ConfigureAwait(false); }
public override Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default) { if (_resetOnEnd) { Reset(); } return(base.EndDialogAsync(turnContext, instance, reason, cancellationToken)); }
/// <summary> /// Called when the dialog is ending. /// </summary> /// <param name="turnContext">The context object for this turn.</param> /// <param name="instance">State information associated with the instance of this dialog on the dialog stack.</param> /// <param name="reason">Reason why the dialog ended.</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> public override Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default) { LoadDialogOptions(turnContext, instance); return(base.EndDialogAsync(turnContext, instance, reason, cancellationToken)); }
/// <summary> /// Resume is called when a child dialog completes and we need to carry on processing in this class. /// </summary> /// <param name="dialogContext">A handle on the runtime.</param> /// <param name="reason">The reason we have control back in this dialog.</param> /// <param name="result">The result from the child dialog. For example this is the value from a prompt.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A DialogTurnResult indicating the state of this dialog to the caller.</returns> public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dialogContext, DialogReason reason, object result, CancellationToken cancellationToken = default(CancellationToken)) { if (dialogContext == null) { throw new ArgumentNullException(nameof(dialogContext)); } // Update the state with the result from the child prompt. var slotName = (string)dialogContext.ActiveDialog.State[SlotName]; var values = GetPersistedValues(dialogContext.ActiveDialog); values[slotName] = result; // Run prompt. return(await RunPromptAsync(dialogContext, cancellationToken)); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default) { if ((string)result == "d2") { return(await dc.EndDialogAsync()); } var name = dc.State.GetValue <string>("$name"); await dc.Context.SendActivityAsync(name); name = dc.State.GetValue <string>("dialog.name"); await dc.Context.SendActivityAsync(name); return(await dc.BeginDialogAsync("d2")); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default) { string nextStep = (string)dc.ActiveDialog.State["stepID"]; dc.ActiveDialog.State[nextStep] = dc.Context.Activity.Text; return(await ContinueDialogAsync(dc, cancellationToken)); }
internal WaterfallStepContext(WaterfallDialog parent, DialogContext dc, object options, IDictionary <string, object> values, int index, DialogReason reason, object result = null) : base(dc.Dialogs, dc.Context, new DialogState(dc.Stack)) { _parent = parent; _nextCalled = false; Index = index; Options = options; Reason = reason; Result = result; Values = values; }
public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken) { if (reason == DialogReason.CancelCalled) { // when dialog is being ended/cancelled, send an activity to skill // to cancel all dialogs on the skill side if (_skillTransport != null) { await _skillTransport.CancelRemoteDialogsAsync(turnContext); } } await base.EndDialogAsync(turnContext, instance, reason, cancellationToken); }
public override Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { return(null); }
public override async Task DialogEndAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken)) { // Notify inner dialog var dialogState = (DialogState)instance.State[PersistedDialogState]; var cdc = new DialogContext(_dialogs, turnContext, dialogState); await OnDialogEndAsync(cdc, reason, cancellationToken).ConfigureAwait(false); }
/// <summary> /// Called when the dialog is ending. /// </summary> /// <param name="turnContext">The context object for this turn.</param> /// <param name="instance">State information associated with the instance of this component /// dialog on its parent's dialog stack.</param> /// <param name="reason">Reason why the dialog ended.</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> /// <remarks>When this method is called from the parent dialog's context, the component dialog /// cancels all of the dialogs on its inner dialog stack before ending.</remarks> /// <seealso cref="OnEndDialogAsync(ITurnContext, DialogInstance, DialogReason, CancellationToken)"/> /// <seealso cref="DialogContext.EndDialogAsync(object, CancellationToken)"/> public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken)) { // Forward cancel to inner dialogs if (reason == DialogReason.CancelCalled) { var innerDc = this.CreateInnerDc(turnContext, instance); await innerDc.CancelAllDialogsAsync(cancellationToken : cancellationToken).ConfigureAwait(false); } await OnEndDialogAsync(turnContext, instance, reason, cancellationToken).ConfigureAwait(false); }
protected override Task OnEndDialogAsync(ITurnContext context, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default) { // Capture the end reason for assertions. EndReason = reason; return(base.OnEndDialogAsync(context, instance, reason, cancellationToken)); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { // Prompts are typically leaf nodes on the stack but the dev is free to push other dialogs // on top of the stack which will result in the prompt receiving an unexpected call to // dialogResume() when the pushed on dialog ends. // To avoid the prompt prematurely ending we need to implement this method and // simply re-prompt the user. await RepromptDialogAsync(dc.Context, dc.ActiveDialog).ConfigureAwait(false); return(Dialog.EndOfTurn); }
/// <summary> /// Called when the dialog is ending. /// </summary> /// <param name="turnContext">Context for the current turn of conversation.</param> /// <param name="instance">The instance of the current dialog.</param> /// <param name="reason">he reason the dialog is ending.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A task that represents the work queued to execute.</returns> public override Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken)) { if (reason == DialogReason.CancelCalled) { // Create step context var index = Convert.ToInt32(instance.State[StepIndex]); var stepName = WaterfallStepName(index); var instanceId = instance.State[PersistedInstanceId] as string; var properties = new Dictionary <string, string>() { { "DialogId", Id }, { "StepName", stepName }, { "InstanceId", instanceId }, }; TelemetryClient.TrackEvent("WaterfallCancel", properties); } else if (reason == DialogReason.EndCalled) { var instanceId = instance.State[PersistedInstanceId] as string; var properties = new Dictionary <string, string>() { { "DialogId", Id }, { "InstanceId", instanceId }, }; TelemetryClient.TrackEvent("WaterfallComplete", properties); } return(Task.CompletedTask); }