From 6b592587d5468c63dd583cbb7c70307c63eec62c Mon Sep 17 00:00:00 2001 From: Qiong Wu Date: Mon, 29 Jul 2019 19:21:31 +0800 Subject: [PATCH 1/7] fallback rule in email and VA --- lib/csharp/Directory.Build.props | 2 +- skills/src/csharp/Skills.sln | 20 +++++ .../emailskill/Dialogs/MainDialog.cs | 1 + .../emailskill/Dialogs/ShowEmailDialog.cs | 75 +++++++++++++++++- .../emailskill/emailskill/EmailSkill.csproj | 7 +- .../Responses/Shared/EmailSharedResponses.cs | 1 + .../Shared/EmailSharedResponses.de.json | Bin 27180 -> 27904 bytes .../Shared/EmailSharedResponses.es.json | Bin 26566 -> 27214 bytes .../Shared/EmailSharedResponses.fr.json | Bin 27264 -> 28004 bytes .../Shared/EmailSharedResponses.it.json | Bin 25666 -> 26274 bytes .../Shared/EmailSharedResponses.json | 9 +++ .../Shared/EmailSharedResponses.zh.json | Bin 17042 -> 17482 bytes .../emailskill/Utilities/Actions.cs | 6 +- .../Dialogs/MainDialog.cs | 25 +++++- .../Services/SkillIntentRecognizer.cs | 42 ++++++++++ .../Sample/VirtualAssistantSample/Startup.cs | 6 +- .../VirtualAssistantSample.csproj | 7 +- .../csharp/VirtualAssistantTemplate.sln | 24 +++++- 18 files changed, 212 insertions(+), 13 deletions(-) create mode 100644 templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Services/SkillIntentRecognizer.cs diff --git a/lib/csharp/Directory.Build.props b/lib/csharp/Directory.Build.props index a94dd79a72..52d2023641 100644 --- a/lib/csharp/Directory.Build.props +++ b/lib/csharp/Directory.Build.props @@ -8,7 +8,7 @@ - True + False diff --git a/skills/src/csharp/Skills.sln b/skills/src/csharp/Skills.sln index 9673e3a1d7..f8f4cbe375 100644 --- a/skills/src/csharp/Skills.sln +++ b/skills/src/csharp/Skills.sln @@ -37,6 +37,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WeatherSkill", "experimenta EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BingSearchSkill", "experimental\bingsearchskill\bingsearchskill\BingSearchSkill.csproj", "{8CB101FA-B496-4507-80A2-151FAB7E8ED1}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Skills", "..\..\..\lib\csharp\microsoft.bot.builder.skills\Microsoft.Bot.Builder.Skills\Microsoft.Bot.Builder.Skills.csproj", "{B25E0652-3BCE-4EEE-86CB-F38660CC9736}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Solutions", "..\..\..\lib\csharp\microsoft.bot.builder.solutions\microsoft.bot.builder.solutions\Microsoft.Bot.Builder.Solutions.csproj", "{2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug - NuGet Packages|Any CPU = Debug - NuGet Packages|Any CPU @@ -157,6 +161,22 @@ Global {8CB101FA-B496-4507-80A2-151FAB7E8ED1}.Documentation|Any CPU.Build.0 = Debug|Any CPU {8CB101FA-B496-4507-80A2-151FAB7E8ED1}.Release|Any CPU.ActiveCfg = Release|Any CPU {8CB101FA-B496-4507-80A2-151FAB7E8ED1}.Release|Any CPU.Build.0 = Release|Any CPU + {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Debug - NuGet Packages|Any CPU.ActiveCfg = Debug - NuGet Packages|Any CPU + {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Debug - NuGet Packages|Any CPU.Build.0 = Debug - NuGet Packages|Any CPU + {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Documentation|Any CPU.Build.0 = Documentation|Any CPU + {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Release|Any CPU.Build.0 = Release|Any CPU + {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Debug - NuGet Packages|Any CPU.ActiveCfg = Debug - NuGet Packages|Any CPU + {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Debug - NuGet Packages|Any CPU.Build.0 = Debug - NuGet Packages|Any CPU + {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Documentation|Any CPU.Build.0 = Documentation|Any CPU + {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/skills/src/csharp/emailskill/emailskill/Dialogs/MainDialog.cs b/skills/src/csharp/emailskill/emailskill/Dialogs/MainDialog.cs index c8bf26d94f..ef6ab31bb0 100644 --- a/skills/src/csharp/emailskill/emailskill/Dialogs/MainDialog.cs +++ b/skills/src/csharp/emailskill/emailskill/Dialogs/MainDialog.cs @@ -211,6 +211,7 @@ private async Task PopulateStateFromSkillContext(ITurnContext context) switch (dc.Context.Activity.Name) { case TokenEvents.TokenResponseEventName: + case SkillEvents.FallbackHandledEventName: { // Auth dialog completion var result = await dc.ContinueDialogAsync(); diff --git a/skills/src/csharp/emailskill/emailskill/Dialogs/ShowEmailDialog.cs b/skills/src/csharp/emailskill/emailskill/Dialogs/ShowEmailDialog.cs index a6d3096118..b24749e5e0 100644 --- a/skills/src/csharp/emailskill/emailskill/Dialogs/ShowEmailDialog.cs +++ b/skills/src/csharp/emailskill/emailskill/Dialogs/ShowEmailDialog.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using EmailSkill.Adapters; using EmailSkill.Extensions; using EmailSkill.Models; using EmailSkill.Responses.Shared; @@ -14,10 +15,13 @@ using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Dialogs; using Microsoft.Bot.Builder.Skills; +using Microsoft.Bot.Builder.Skills.Models; +using Microsoft.Bot.Builder.Solutions; using Microsoft.Bot.Builder.Solutions.Resources; using Microsoft.Bot.Builder.Solutions.Responses; using Microsoft.Bot.Builder.Solutions.Util; using Microsoft.Bot.Connector.Authentication; +using Microsoft.Bot.Schema; using Microsoft.Graph; namespace EmailSkill.Dialogs @@ -96,6 +100,13 @@ public ShowEmailDialog( HandleMore, }; + var retryUnknown = new WaterfallStep[] + { + SendFallback, + RetryInput, + HandleMore, + }; + // Define the conversation flow using a waterfall model. AddDialog(new WaterfallDialog(Actions.Show, showEmail) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.Read, readEmail) { TelemetryClient = telemetryClient }); @@ -105,9 +116,11 @@ public ShowEmailDialog( AddDialog(new WaterfallDialog(Actions.Display, displayEmail) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.DisplayFiltered, displayFilteredEmail) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.ReDisplay, redisplayEmail) { TelemetryClient = telemetryClient }); + AddDialog(new WaterfallDialog(Actions.RetryUnknown, retryUnknown) { TelemetryClient = telemetryClient }); AddDialog(deleteEmailDialog ?? throw new ArgumentNullException(nameof(deleteEmailDialog))); AddDialog(replyEmailDialog ?? throw new ArgumentNullException(nameof(replyEmailDialog))); AddDialog(forwardEmailDialog ?? throw new ArgumentNullException(nameof(forwardEmailDialog))); + AddDialog(new EventPrompt(Actions.FallbackEventPrompt, SkillEvents.FallbackHandledEventName, ResponseValidatorAsync)); InitialDialogId = Actions.Show; } @@ -372,6 +385,9 @@ public ShowEmailDialog( } else { + var cachedMessageList = state.MessageList; + var cachedFocusedMessages = state.Message; + await DigestEmailLuisResult(sc, state.LuisResult, true); await SearchEmailsFromList(sc, cancellationToken); @@ -380,9 +396,10 @@ public ShowEmailDialog( return await sc.ReplaceDialogAsync(Actions.DisplayFiltered, skillOptions); } - // return a signal for main flow need to start a new ComponentDialog. - await sc.Context.SendActivityAsync(ResponseManager.GetResponse(EmailSharedResponses.DidntUnderstandMessage)); - return await sc.EndDialogAsync(true); + state.MessageList = cachedMessageList; + state.Message = cachedFocusedMessages; + + return await sc.ReplaceDialogAsync(Actions.RetryUnknown, skillOptions); } } catch (Exception ex) @@ -534,5 +551,57 @@ public ShowEmailDialog( return new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs); } } + + protected Task ResponseValidatorAsync(PromptValidatorContext pc, CancellationToken cancellationToken) + { + var activity = pc.Recognized.Value; + if (activity != null && activity.Type == ActivityTypes.Event && activity.Name == SkillEvents.FallbackHandledEventName) + { + return Task.FromResult(true); + } + + return Task.FromResult(false); + } + + protected async Task SendFallback(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) + { + try + { + var state = await EmailStateAccessor.GetAsync(sc.Context); + + // Send Fallback Event + if (sc.Context.Adapter is EmailSkillWebSocketBotAdapter remoteInvocationAdapter) + { + await remoteInvocationAdapter.SendRemoteFallbackEventAsync(sc.Context, cancellationToken).ConfigureAwait(false); + + // Wait for the FallbackHandle event + return await sc.PromptAsync(Actions.FallbackEventPrompt, new PromptOptions()).ConfigureAwait(false); + } + + return await sc.NextAsync(); + } + catch (Exception ex) + { + await HandleDialogExceptions(sc, ex); + + return new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs); + } + } + + protected async Task RetryInput(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) + { + try + { + var state = await EmailStateAccessor.GetAsync(sc.Context); + + return await sc.PromptAsync(Actions.Prompt, new PromptOptions { Prompt = ResponseManager.GetResponse(EmailSharedResponses.RetryInput) }); + } + catch (Exception ex) + { + await HandleDialogExceptions(sc, ex); + + return new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs); + } + } } } \ No newline at end of file diff --git a/skills/src/csharp/emailskill/emailskill/EmailSkill.csproj b/skills/src/csharp/emailskill/emailskill/EmailSkill.csproj index 5eeadfeeab..68e0ee2d28 100644 --- a/skills/src/csharp/emailskill/emailskill/EmailSkill.csproj +++ b/skills/src/csharp/emailskill/emailskill/EmailSkill.csproj @@ -44,8 +44,6 @@ - - @@ -179,6 +177,11 @@ + + + + + diff --git a/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.cs b/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.cs index 5211e00d89..41a7b1ef49 100644 --- a/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.cs +++ b/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.cs @@ -40,5 +40,6 @@ public class EmailSharedResponses : IResponseIdCollection public const string LastPageAlready = "LastPageAlready"; public const string NoChoiceOptionsRetry = "NoChoiceOptionsRetry"; public const string NoRecipients = "NoRecipients"; + public const string RetryInput = "RetryInput"; } } diff --git a/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.de.json b/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.de.json index 7ffa65259ec1bb4c234f3154d2bc143f0b78ab6b..be6fd17bb63af70bf8824985fb76563ff11a2c35 100644 GIT binary patch delta 370 zcmZ2;g|Xol;|2}($pwrulO5PQCL6@dO%6!mnH<2LHo1ncZu2D$Ehea>z~q<|lgWHM zUX$;o2tgG(Z06&!VgxHl;O&9yF5u1DT*D{81C)@Myg({r@&j41%~H}89FvT+Ci|%* zOqNg)ntZ@WW3!)%0M{fVg~<-?9Fx8Dtv2t`yJS3hgO=1}u4ISFY$h6;Ig)iC#yhZs z?4JU)q7Upiu{0i*$qK4GoIwn!3?&Rj43(2(1LG%uU=&bvWyk}H6f-0pYw`ij1TJ0%E{0kL5D5SeDsHs^ delta 215 zcmZp;#kl4Q;|2}($@64HCOfeAOn%2GHd#(kV6qmU%;W-gugx(WE11BN4JjUz<#@a% zuj3YiD>C4&n;gSYH~CL8$K-cBSzvVqyc1yZo3;3=c))^tq%welLYu9mD>x>fQ24k$li^EH(XoRjalscc@S$73>iUsA^8I75-mcF9_dP)DqQ89v#7 a+hp>I6hDvyHV38guyFA*a52;}fJgwh5=%A! diff --git a/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.es.json b/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.es.json index 4b8c6cc56d688188663b5bce52fed2c7c0a6e5d4..f7598c8f70ef8237820c04fb81387235423e531a 100644 GIT binary patch delta 269 zcmX?hp7Goj#s%z?HwZ~g;^vwx$39`QftlFm1ME7?5V12L{^SGfT$AS{`c1ZCPntY~ z=L1Z69ADRD13n?B61B}$eCN19a+71EqQK^ykXpq77HCs$0}IHheBcBMNNrZpn_&o+ zxe%W;S;1Fovqyp%BS>Hpcf{mZi492B?wRbtQMdU(@*n2O1#CQ=K@6!3B@9Ijm6Ol= z#ZSJVEiu{7mv8b7ey@;h#>$-8)EHos$MV}?p{P5!~XVe$fY zA&`R2@3>bnLM4_V>FCCM=2|kkp5+KG`Bv`?W2ifa4Ss*zNW;f7r5t{{)U$AiTGH@}}GJr?`uXsmU diff --git a/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.fr.json b/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.fr.json index c7f6306c31e3f30c01d2eae0638589ebdba6aa34..278e754d195793c9cc7de25025fb86fc4d44665d 100644 GIT binary patch delta 339 zcmZp;%J}3KlizR)Os-(BnA{MrFgcICU~>(}0w$=$gvky18k6PtL^l87 zE?`7bEiriwZvs?@5|HgTxrU=|vlu@Y_v8tlQj^W3vL-t?NC4@G%{_ff^V{sv&`fKR-ws$K@#K{@JOMIikJk@LT>;DhpgNt&2YCH9Z{X|Tp3LVUHu;KF#N<^{LX-Wx zL^fZM`o}Rjj#XsxE9Jb&dFmpY3siczzybwEY?Bo{xHhZk-!ldaNF}F$?UhOnntV#d kYqCMg0wnuD?lPLJmzsd&HW1$r_c%0IvN{X8-^I diff --git a/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.it.json b/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.it.json index c98c6046a7f7e77b397936c7510d9c53eeb478ca..ef8119c32f462c0a20e9b1f23f5f4315cb18f263 100644 GIT binary patch delta 350 zcmX?ff^pGV#tl5|lQ#%TOjcm8n5@7ows{ph7xQER4XMd{oH!;=;GQt~Oq>u%V)BQ$ zpvgAuLX&m4%_b}Ge1K|_ne4!u29{sN4q}H)7T~Dcyo_%hCs;v-L>SoA3leD@U;!`1 z9I$FH#i+>|e07@_C^>P$tlOlMVE|MlHMuS(3asl@j0q!566h9>$t`gZi4Soetdl>; z@dyVoq%xE+6fsmXcrxTM6fl%BluSOT9y(u?$$8vD zllN(gOxBAJ04fmL{EJ(S5vsFk^FH2nTwqR%MA+tg5)~X^PM%`U=6i}dT$}lH+6=%V oYhq$1z7yIk7i$923o_Vaa$UR!%<#>6@oubKybN3nwG1E<0AR5*y8r+H diff --git a/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.json b/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.json index 3bdc0bbe9e..99d0061c17 100644 --- a/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.json +++ b/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.json @@ -378,5 +378,14 @@ } ], "inputHint": "expectingInput" + }, + "RetryInput": { + "replies": [ + { + "text": "Sorry, I don't understand what you mean. Could you please try again?", + "speak": "Sorry, I don't understand what you mean. Could you please try again?" + } + ], + "inputHint": "expectingInput" } } diff --git a/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.zh.json b/skills/src/csharp/emailskill/emailskill/Responses/Shared/EmailSharedResponses.zh.json index 429d83885ad3764267736ffb883b3da8aba24040..3a0f37c8bacf5b00af74be724ef0fbb05ceeddae 100644 GIT binary patch delta 265 zcmbQ#%6O`Sal;#y$sc&6CNr@{O-_&$+nmQbiwP_s$B_pXn8)GA2vNZWRl#+RZL$HQ z#N+@$2at+M%p99n3C>^zi>(mXn|y{}Yx64c17Ly8b+T^qV3`{>c3|@~Y{ekv$#JMm z{$pn~`JAlAkJ!Ma03&^LY*}O*9MINl2 s!`2R{OlWhAtr*16F1sR-Et5BJs7&5qXEpf%Yu)A#_E(rDJGgKG00j_00RR91 diff --git a/skills/src/csharp/emailskill/emailskill/Utilities/Actions.cs b/skills/src/csharp/emailskill/emailskill/Utilities/Actions.cs index 2c5fda223a..44bcc255d7 100644 --- a/skills/src/csharp/emailskill/emailskill/Utilities/Actions.cs +++ b/skills/src/csharp/emailskill/emailskill/Utilities/Actions.cs @@ -44,6 +44,10 @@ public class Actions public const string Help = "help"; - public const string GetRecreateInfoPrompt = "GetRecreateInfoPrompt"; + public const string GetRecreateInfoPrompt = "getRecreateInfoPrompt"; + + public const string FallbackEventPrompt = "fallbackEventPrompt"; + + public const string RetryUnknown = "retryUnknown"; } } \ No newline at end of file diff --git a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs index f675ed759c..b77d333bfb 100644 --- a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs +++ b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs @@ -11,6 +11,8 @@ using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Dialogs; using Microsoft.Bot.Builder.Skills; +using Microsoft.Bot.Builder.Skills.Dialogs; +using Microsoft.Bot.Builder.Skills.Models; using Microsoft.Bot.Builder.Solutions; using Microsoft.Bot.Builder.Solutions.Dialogs; using Microsoft.Bot.Schema; @@ -22,7 +24,7 @@ namespace VirtualAssistantSample.Dialogs { - public class MainDialog : RouterDialog + public class MainDialog : DispatchDialog { private const string Location = "location"; private const string TimeZone = "timezone"; @@ -184,6 +186,27 @@ public MainDialog( } } + protected override async Task RedispatchAsync(DialogContext innerDc, DialogTurnResult result = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var intent = result.Result as DispatchIntent; + + // Identify if the dispatch intent matches any Action within a Skill if so, we pass to the appropriate SkillDialog to hand-off + var identifiedSkill = SkillRouter.IsSkill(_settings.Skills, intent.Intent.ToString()); + + if (identifiedSkill != null) + { + // We have identiifed a skill so initialize the skill connection with the target skill + var dialogResult = await innerDc.BeginDialogAsync(identifiedSkill.Id); + + if (dialogResult.Status == DialogTurnStatus.Complete) + { + await CompleteAsync(innerDc); + } + } + + await base.RedispatchAsync(innerDc, result, cancellationToken); + } + protected override async Task OnEventAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { // Check if there was an action submitted from intro card diff --git a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Services/SkillIntentRecognizer.cs b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Services/SkillIntentRecognizer.cs new file mode 100644 index 0000000000..f311364718 --- /dev/null +++ b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Services/SkillIntentRecognizer.cs @@ -0,0 +1,42 @@ +using System; +using System.Globalization; +using System.Threading; +using System.Threading.Tasks; +using Luis; +using Microsoft.Bot.Builder.Dialogs; +using Microsoft.Bot.Builder.Skills; +using VirtualAssistantSample.Services; + +namespace VirtualAssistantSample +{ + public class SkillIntentRecognizer : ISkillIntentRecognizer + { + private BotServices _services; + private BotSettings _settings; + private bool _confirmIntentSwitch = true; + + public SkillIntentRecognizer(BotServices services, BotSettings settings) + { + _services = services; + _settings = settings; + } + + public async Task RecognizeSkillIntentAsyncFunc(DialogContext dc) + { + var locale = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; + var cognitiveModels = _services.CognitiveModelSets[locale]; + + // Check dispatch result + var dispatchResult = await cognitiveModels.DispatchService.RecognizeAsync(dc.Context, CancellationToken.None); + var intent = dispatchResult.TopIntent().intent; + + // Identify if the dispatch intent matches any action within a Skill if so, we pass to the appropriate SkillDialog to hand-off + var recognizeSkill = SkillRouter.IsSkill(_settings.Skills, intent.ToString()); + return recognizeSkill?.Id; + } + + public Func> RecognizeSkillIntentAsync { get { return RecognizeSkillIntentAsyncFunc; } } + + public bool ConfirmIntentSwitch { get { return _confirmIntentSwitch; } } + } +} \ No newline at end of file diff --git a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Startup.cs b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Startup.cs index b6fe723947..7d564786bf 100644 --- a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Startup.cs +++ b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Startup.cs @@ -93,17 +93,21 @@ public void ConfigureServices(IServiceCollection services) services.AddTransient(); services.AddTransient(); + // Register recognizer + services.AddTransient(); + // Register skill dialogs services.AddTransient(sp => { var userState = sp.GetService(); var skillDialogs = new List(); + var intentRecognizer = sp.GetService(); foreach (var skill in settings.Skills) { var authDialog = BuildAuthDialog(skill, settings, appCredentials); var credentials = new MicrosoftAppCredentialsEx(settings.MicrosoftAppId, settings.MicrosoftAppPassword, skill.MSAappId); - skillDialogs.Add(new SkillDialog(skill, credentials, telemetryClient, userState, authDialog)); + skillDialogs.Add(new SkillDialog(skill, credentials, telemetryClient, userState, authDialog, intentRecognizer)); } return skillDialogs; diff --git a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/VirtualAssistantSample.csproj b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/VirtualAssistantSample.csproj index 499eaec568..6f1dbea419 100644 --- a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/VirtualAssistantSample.csproj +++ b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/VirtualAssistantSample.csproj @@ -25,8 +25,6 @@ - - @@ -37,6 +35,11 @@ + + + + + PublicResXFileCodeGenerator diff --git a/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln b/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln index 9a690c828f..b4475e5ec7 100644 --- a/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln +++ b/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29009.5 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.539 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VSIX", "VSIX", "{4FA953A9-9057-41A2-820D-6D07CA1206AE}" EndProject @@ -13,6 +13,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtualAssistantSample.Test EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualAssistantVSIX", "VSIX\VirtualAssistantVSIX.csproj", "{794F4E29-D65D-4F5F-9B04-55FFD5EE864D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Skills", "..\..\..\lib\csharp\microsoft.bot.builder.skills\Microsoft.Bot.Builder.Skills\Microsoft.Bot.Builder.Skills.csproj", "{8807EF9A-9974-4E7F-ADBD-B9E916039155}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Solutions", "..\..\..\lib\csharp\microsoft.bot.builder.solutions\microsoft.bot.builder.solutions\Microsoft.Bot.Builder.Solutions.csproj", "{988FB3D7-0251-4B0D-BA05-60B5DDF08743}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug - NuGet Packages|Any CPU = Debug - NuGet Packages|Any CPU @@ -45,6 +49,22 @@ Global {794F4E29-D65D-4F5F-9B04-55FFD5EE864D}.Documentation|Any CPU.Build.0 = Debug|Any CPU {794F4E29-D65D-4F5F-9B04-55FFD5EE864D}.Release|Any CPU.ActiveCfg = Release|Any CPU {794F4E29-D65D-4F5F-9B04-55FFD5EE864D}.Release|Any CPU.Build.0 = Release|Any CPU + {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Debug - NuGet Packages|Any CPU.ActiveCfg = Debug - NuGet Packages|Any CPU + {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Debug - NuGet Packages|Any CPU.Build.0 = Debug - NuGet Packages|Any CPU + {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Documentation|Any CPU.Build.0 = Documentation|Any CPU + {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Release|Any CPU.Build.0 = Release|Any CPU + {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Debug - NuGet Packages|Any CPU.ActiveCfg = Debug - NuGet Packages|Any CPU + {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Debug - NuGet Packages|Any CPU.Build.0 = Debug - NuGet Packages|Any CPU + {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Debug|Any CPU.Build.0 = Debug|Any CPU + {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Documentation|Any CPU.Build.0 = Documentation|Any CPU + {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Release|Any CPU.ActiveCfg = Release|Any CPU + {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 1759b96bac8677199cf794d2321c176985bcff69 Mon Sep 17 00:00:00 2001 From: Qiong Wu Date: Mon, 29 Jul 2019 20:26:35 +0800 Subject: [PATCH 2/7] add calendar support --- .../calendarskill/CalendarSkill.csproj | 7 +- .../calendarskill/Dialogs/MainDialog.cs | 1 + .../calendarskill/Dialogs/SummaryDialog.cs | 66 ++++- .../Shared/CalendarSharedResponses.cs | 1 + .../Shared/CalendarSharedResponses.de.json | Bin 7236 -> 7900 bytes .../Shared/CalendarSharedResponses.es.json | Bin 6448 -> 7036 bytes .../Shared/CalendarSharedResponses.fr.json | Bin 7104 -> 7784 bytes .../Shared/CalendarSharedResponses.it.json | Bin 6520 -> 7068 bytes .../Shared/CalendarSharedResponses.json | 185 +++++++------ .../Shared/CalendarSharedResponses.zh.json | 261 +++++++++--------- .../calendarskill/Utilities/Actions.cs | 2 + 11 files changed, 306 insertions(+), 217 deletions(-) diff --git a/skills/src/csharp/calendarskill/calendarskill/CalendarSkill.csproj b/skills/src/csharp/calendarskill/calendarskill/CalendarSkill.csproj index e0e1badd30..f12aae2658 100644 --- a/skills/src/csharp/calendarskill/calendarskill/CalendarSkill.csproj +++ b/skills/src/csharp/calendarskill/calendarskill/CalendarSkill.csproj @@ -104,8 +104,6 @@ - - @@ -195,6 +193,11 @@ + + + + + True diff --git a/skills/src/csharp/calendarskill/calendarskill/Dialogs/MainDialog.cs b/skills/src/csharp/calendarskill/calendarskill/Dialogs/MainDialog.cs index 010ec8e3fc..d71a874a62 100644 --- a/skills/src/csharp/calendarskill/calendarskill/Dialogs/MainDialog.cs +++ b/skills/src/csharp/calendarskill/calendarskill/Dialogs/MainDialog.cs @@ -224,6 +224,7 @@ private async Task PopulateStateFromSemanticAction(ITurnContext context) switch (dc.Context.Activity.Name) { case TokenEvents.TokenResponseEventName: + case SkillEvents.FallbackHandledEventName: { // Auth dialog completion var result = await dc.ContinueDialogAsync(); diff --git a/skills/src/csharp/calendarskill/calendarskill/Dialogs/SummaryDialog.cs b/skills/src/csharp/calendarskill/calendarskill/Dialogs/SummaryDialog.cs index c490bdb9c4..6a2f6542df 100644 --- a/skills/src/csharp/calendarskill/calendarskill/Dialogs/SummaryDialog.cs +++ b/skills/src/csharp/calendarskill/calendarskill/Dialogs/SummaryDialog.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using CalendarSkill.Adapters; using CalendarSkill.Models; using CalendarSkill.Responses.Shared; using CalendarSkill.Responses.Summary; @@ -13,6 +14,8 @@ using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Dialogs; using Microsoft.Bot.Builder.Skills; +using Microsoft.Bot.Builder.Skills.Models; +using Microsoft.Bot.Builder.Solutions; using Microsoft.Bot.Builder.Solutions.Resources; using Microsoft.Bot.Builder.Solutions.Responses; using Microsoft.Bot.Builder.Solutions.Util; @@ -69,6 +72,13 @@ public SummaryDialog( AfterReadOutEvent, }; + var retryUnknown = new WaterfallStep[] + { + SendFallback, + RetryInput, + HandleActions, + }; + // Define the conversation flow using a waterfall model. AddDialog(new WaterfallDialog(Actions.GetEventsInit, initStep) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.ShowNextEvent, showNext) { TelemetryClient = telemetryClient }); @@ -76,6 +86,8 @@ public SummaryDialog( AddDialog(new WaterfallDialog(Actions.Read, readEvent) { TelemetryClient = telemetryClient }); AddDialog(updateEventDialog ?? throw new ArgumentNullException(nameof(updateEventDialog))); AddDialog(changeEventStatusDialog ?? throw new ArgumentNullException(nameof(changeEventStatusDialog))); + AddDialog(new WaterfallDialog(Actions.RetryUnknown, retryUnknown) { TelemetryClient = telemetryClient }); + AddDialog(new EventPrompt(Actions.FallbackEventPrompt, SkillEvents.FallbackHandledEventName, ResponseValidatorAsync)); // Set starting dialog for component InitialDialogId = Actions.GetEventsInit; @@ -641,7 +653,7 @@ await sc.Context.SendActivityAsync(await GetOverviewMeetingListResponseAsync( return await sc.BeginDialogAsync(Actions.Read, sc.Options); } - return await sc.NextAsync(); + return await sc.ReplaceDialogAsync(Actions.RetryUnknown, sc.Options); } catch (Exception ex) { @@ -831,5 +843,57 @@ private bool SearchesTodayMeeting(CalendarSkillState state) !state.EndTime.Any() && EventModel.IsSameDate(searchDate, userNow); } + + protected Task ResponseValidatorAsync(PromptValidatorContext pc, CancellationToken cancellationToken) + { + var activity = pc.Recognized.Value; + if (activity != null && activity.Type == ActivityTypes.Event && activity.Name == SkillEvents.FallbackHandledEventName) + { + return Task.FromResult(true); + } + + return Task.FromResult(false); + } + + protected async Task SendFallback(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) + { + try + { + var state = await Accessor.GetAsync(sc.Context); + + // Send Fallback Event + if (sc.Context.Adapter is CalendarSkillWebSocketBotAdapter remoteInvocationAdapter) + { + await remoteInvocationAdapter.SendRemoteFallbackEventAsync(sc.Context, cancellationToken).ConfigureAwait(false); + + // Wait for the FallbackHandle event + return await sc.PromptAsync(Actions.FallbackEventPrompt, new PromptOptions()).ConfigureAwait(false); + } + + return await sc.NextAsync(); + } + catch (Exception ex) + { + await HandleDialogExceptions(sc, ex); + + return new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs); + } + } + + protected async Task RetryInput(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) + { + try + { + var state = await Accessor.GetAsync(sc.Context); + + return await sc.PromptAsync(Actions.Prompt, new PromptOptions { Prompt = ResponseManager.GetResponse(CalendarSharedResponses.RetryInput) }); + } + catch (Exception ex) + { + await HandleDialogExceptions(sc, ex); + + return new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs); + } + } } } \ No newline at end of file diff --git a/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.cs b/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.cs index bc57055d4e..ae98435119 100644 --- a/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.cs +++ b/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.cs @@ -16,5 +16,6 @@ public class CalendarSharedResponses : IResponseIdCollection public const string ActionEnded = "ActionEnded"; public const string CalendarErrorMessage = "CalendarErrorMessage"; public const string CalendarErrorMessageBotProblem = "CalendarErrorMessageBotProblem"; + public const string RetryInput = "RetryInput"; } } diff --git a/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.de.json b/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.de.json index 0bbe45ee70aac2b646dfd3f5bf232f01b4da0b85..8397f86de8926e0c9f1a03ee5f6ae6e2923ecd9b 100644 GIT binary patch delta 249 zcmX?NamRLpmCWQgW**@nhE#?Uh9ZVa22X}Oh609ChLXvQ0-=)~M1>slfHK7l$qX4l z(Hw>phD?TZAS(|@>M$q(c_0}DhBBZDML=~WKsp166@V%rawU`F`Q#ZDCL3}|PF%po nnFJIr0V$j8C?q*qK-6Gzf`|yMEs>a9#VIs7k3V6ul?)dEaAP-` delta 18 Xcmca(d&FXcl?)dz0~bRr1Be6wHFpEi diff --git a/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.es.json b/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.es.json index f18a82e87b732827f26401eb3bf72f1ddf433c27..643024d347d641799d9050ba7bb7f81a2065de40 100644 GIT binary patch delta 130 zcmdmB^v7(2n&jkjOgzFt45m3gfW0ET>q6rj4d42hE+ITR;1uyQflPkzWHJ$WCW(BvFuB?2lB@|JS(GH@}}GJr?` Dq%XDw89W*C7z!9l8A>L96c3&3z$Gwwju_A62h4Je zDU%slq$khg=MYW>%2zNbFr+YK0`;Ua=rJfv_UDpiES`LxOMY?+tH5LtX`#uNIAkUZ k@Cr>nBOoxjibaZ4{fzdL4>I{q<`U50;$`4ssAT|=0Br*-*Z=?k delta 11 ScmaE1bHIGVHtET6a$Eo+8U(fg diff --git a/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.it.json b/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.it.json index 165551a6fe1cbb741d2bfb8653c4de25a8895045..bcbc78262406a0484fdcf204d4df1c99b0e6819a 100644 GIT binary patch delta 189 zcmexiG{<~Hp5$abJ|5v9hE#?Uh9ZVa22X}Oh609ChLXvNe4&#QLqrHPl`v#ZJ}4k6tizxHRFw)eM}Z*?sH2P_fAVP##mNbr hB9nDkM2Is*5{oH76H^)NCog33oy^9kF*#3?3jjGyEYtu1 delta 18 XcmbPZ{=;ZPo+KA90~bRr1Be6wHTMJR diff --git a/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.json b/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.json index 45917a8ff8..338ad4d17e 100644 --- a/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.json +++ b/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.json @@ -1,90 +1,99 @@ { - "DidntUnderstandMessage": { - "replies": [ - { - "text": "Sorry, I didn't understand what you meant.", - "speak": "Sorry, I didn't understand what you meant." - }, - { - "text": "I didn't understand, perhaps try again in a different way.", - "speak": "I didn't understand, perhaps try again in a different way." - }, - { - "text": "Can you try to ask in a different way?", - "speak": "Can you try to ask in a different way?" - }, - { - "text": "I didn't get what you mean, can you try in a different way?", - "speak": "I didn't get what you mean, can you try in a different way?" - }, - { - "text": "Could you elaborate?", - "speak": "Could you elaborate?" - }, - { - "text": "Please say that again in a different way.", - "speak": "Please say that again in a different way." - }, - { - "text": "I didn't quite get that.", - "speak": "I didn't quite get that." - }, - { - "text": "Can you say that in a different way?", - "speak": "Can you say that in a different way?" - }, - { - "text": "Can you try to ask me again? I didn't get what you mean.", - "speak": "Can you try to ask me again? I didn't get what you mean." - } - ], - "inputHint": "expectingInput" - }, - "ActionEnded": { - "replies": [ - { - "text": "Let me know if you need my help with something else.", - "speak": "Let me know if you need my help with something else." - }, - { - "text": "I'm here if you need me.", - "speak": "I'm here if you need me." - } - ], - "inputHint": "acceptingInput" - }, - "CalendarErrorMessage": { - "replies": [ - { - "text": "Sorry, it looks like something went wrong!", - "speak": "Sorry, it looks like something went wrong!" - }, - { - "text": "An error occurred, please try again later.", - "speak": "An error occurred, please try again later." - }, - { - "text": "Something went wrong, sorry!", - "speak": "Something went wrong, sorry!" - }, - { - "text": "It seems like something went wrong. Can you try again later?", - "speak": "It seems like something went wrong. Can you try again later?" - }, - { - "text": "Sorry I can't help right now. Please try again later.", - "speak": "Sorry I can't help right now. Please try again later." - } - ], - "inputHint": "acceptingInput" - }, - "CalendarErrorMessageBotProblem": { - "replies": [ - { - "text": "Sorry, there is something wrong with the bot at the moment. The developer has been notified about it so you'll be able to perform the action again very soon.", - "speak": "Sorry, there is something wrong with the bot at the moment. The developer has been notified about it so you'll be able to perform the action again very soon." - } - ], - "inputHint": "acceptingInput" - } + "DidntUnderstandMessage": { + "replies": [ + { + "text": "Sorry, I didn't understand what you meant.", + "speak": "Sorry, I didn't understand what you meant." + }, + { + "text": "I didn't understand, perhaps try again in a different way.", + "speak": "I didn't understand, perhaps try again in a different way." + }, + { + "text": "Can you try to ask in a different way?", + "speak": "Can you try to ask in a different way?" + }, + { + "text": "I didn't get what you mean, can you try in a different way?", + "speak": "I didn't get what you mean, can you try in a different way?" + }, + { + "text": "Could you elaborate?", + "speak": "Could you elaborate?" + }, + { + "text": "Please say that again in a different way.", + "speak": "Please say that again in a different way." + }, + { + "text": "I didn't quite get that.", + "speak": "I didn't quite get that." + }, + { + "text": "Can you say that in a different way?", + "speak": "Can you say that in a different way?" + }, + { + "text": "Can you try to ask me again? I didn't get what you mean.", + "speak": "Can you try to ask me again? I didn't get what you mean." + } + ], + "inputHint": "expectingInput" + }, + "ActionEnded": { + "replies": [ + { + "text": "Let me know if you need my help with something else.", + "speak": "Let me know if you need my help with something else." + }, + { + "text": "I'm here if you need me.", + "speak": "I'm here if you need me." + } + ], + "inputHint": "acceptingInput" + }, + "CalendarErrorMessage": { + "replies": [ + { + "text": "Sorry, it looks like something went wrong!", + "speak": "Sorry, it looks like something went wrong!" + }, + { + "text": "An error occurred, please try again later.", + "speak": "An error occurred, please try again later." + }, + { + "text": "Something went wrong, sorry!", + "speak": "Something went wrong, sorry!" + }, + { + "text": "It seems like something went wrong. Can you try again later?", + "speak": "It seems like something went wrong. Can you try again later?" + }, + { + "text": "Sorry I can't help right now. Please try again later.", + "speak": "Sorry I can't help right now. Please try again later." + } + ], + "inputHint": "acceptingInput" + }, + "CalendarErrorMessageBotProblem": { + "replies": [ + { + "text": "Sorry, there is something wrong with the bot at the moment. The developer has been notified about it so you'll be able to perform the action again very soon.", + "speak": "Sorry, there is something wrong with the bot at the moment. The developer has been notified about it so you'll be able to perform the action again very soon." + } + ], + "inputHint": "acceptingInput" + }, + "RetryInput": { + "replies": [ + { + "text": "Sorry, I don't understand what you mean. Could you please try again?", + "speak": "Sorry, I don't understand what you mean. Could you please try again?" + } + ], + "inputHint": "expectingInput" + } } diff --git a/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.zh.json b/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.zh.json index aec4a9b52a..106c22214a 100644 --- a/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.zh.json +++ b/skills/src/csharp/calendarskill/calendarskill/Responses/Shared/CalendarSharedResponses.zh.json @@ -1,128 +1,137 @@ { - "DidntUnderstandMessage": { - "replies": [ - { - "text": "对不起,我没有明白你的意思。", - "speak": "对不起,我没有明白你的意思。" - }, - { - "text": "我没有明白你的意思,请尝试用不同的方式提问。", - "speak": "我没有明白你的意思,请尝试用不同的方式提问。" - }, - { - "text": "你能不能试着用另一种方式问我。", - "speak": "你能不能试着用另一种方式问我。" - }, - { - "text": "我没有明白你的意思,你能以不同的方式尝试吗?", - "speak": "我没有明白你的意思,你能以不同的方式尝试吗?" - }, - { - "text": "你能说得更详细吗?", - "speak": "你能说得更详细吗?" - }, - { - "text": "请以不同的方式再说一遍。", - "speak": "请以不同的方式再说一遍。" - }, - { - "text": "我没有理解你的意思。", - "speak": "我没有理解你的意思。" - }, - { - "text": "你能尝试用不同的表达方式吗?", - "speak": "你能尝试用不同的表达方式吗?" - }, - { - "text": "你能再试一次,我没听懂你的意思。", - "speak": "你能再试一次,我没听懂你的意思。" - } - ], - "inputHint": "expectingInput" - }, - "NoAuth": { - "replies": [ - { - "text": "请登录,以便我采取进一步行动。", - "speak": "请登录,以便我采取进一步行动。" - }, - { - "text": "请登录,以便我可以继续您的请求。", - "speak": "请登录,以便我可以继续您的请求。" - }, - { - "text": "你可以登录,这样我可以帮助你。", - "speak": "你可以登录,这样我可以帮助你。" - }, - { - "text": "您需要登录才能采取进一步行动。", - "speak": "您需要登录才能采取进一步行动。" - } - ], - "inputHint": "acceptingInput" - }, - "AuthFailed": { - "replies": [ - { - "text": "你的身份验证失败,请再试一次。", - "speak": "你的身份验证失败,请再试一次。" - }, - { - "text": "你的登录失败,请稍后再试。", - "speak": "你的登录失败,请稍后再试。" - }, - { - "text": "你的登录失败了,让我们再试一次。", - "speak": "你的登录失败了,让我们再试一次。" - } - ], - "inputHint": "acceptingInput" - }, - "ActionEnded": { - "replies": [ - { - "text": "如果您需要我的帮助,请告诉我。", - "speak": "如果您需要我的帮助,请告诉我。" - }, - { - "text": "如果你需要我,我就在这里。", - "speak": "如果你需要我,我就在这里。" - } - ], - "inputHint": "acceptingInput" - }, - "CalendarErrorMessage": { - "replies": [ - { - "text": "对不起,看起来出了问题!", - "speak": "对不起,看起来出了问题!" - }, - { - "text": "发生错误,给我一些时间,稍后再试。", - "speak": "发生错误,给我一些时间,稍后再试。" - }, - { - "text": "出了点问题,对不起!", - "speak": "出了点问题,对不起!" - }, - { - "text": "我相信出了点问题。你以后可以再试一次吗?", - "speak": "我相信出了点问题。你以后可以再试一次吗?" - }, - { - "text": "对不起我觉得我现在找不到你想要的东西。请稍后再试。", - "speak": "对不起我觉得我现在找不到你想要的东西。请稍后再试。" - } - ], - "inputHint": "acceptingInput" - }, - "CalendarErrorMessageBotProblem": { - "replies": [ - { - "text": "对不起,出了点问题。开发人员已经收到通知并且在解决这个问题。你很快就又可以正常使用这个功能了。", - "speak": "对不起,出了点问题。开发人员已经收到通知并且在解决这个问题。你很快就又可以正常使用这个功能了。" - } - ], - "inputHint": "acceptingInput" - } + "DidntUnderstandMessage": { + "replies": [ + { + "text": "对不起,我没有明白你的意思。", + "speak": "对不起,我没有明白你的意思。" + }, + { + "text": "我没有明白你的意思,请尝试用不同的方式提问。", + "speak": "我没有明白你的意思,请尝试用不同的方式提问。" + }, + { + "text": "你能不能试着用另一种方式问我。", + "speak": "你能不能试着用另一种方式问我。" + }, + { + "text": "我没有明白你的意思,你能以不同的方式尝试吗?", + "speak": "我没有明白你的意思,你能以不同的方式尝试吗?" + }, + { + "text": "你能说得更详细吗?", + "speak": "你能说得更详细吗?" + }, + { + "text": "请以不同的方式再说一遍。", + "speak": "请以不同的方式再说一遍。" + }, + { + "text": "我没有理解你的意思。", + "speak": "我没有理解你的意思。" + }, + { + "text": "你能尝试用不同的表达方式吗?", + "speak": "你能尝试用不同的表达方式吗?" + }, + { + "text": "你能再试一次,我没听懂你的意思。", + "speak": "你能再试一次,我没听懂你的意思。" + } + ], + "inputHint": "expectingInput" + }, + "NoAuth": { + "replies": [ + { + "text": "请登录,以便我采取进一步行动。", + "speak": "请登录,以便我采取进一步行动。" + }, + { + "text": "请登录,以便我可以继续您的请求。", + "speak": "请登录,以便我可以继续您的请求。" + }, + { + "text": "你可以登录,这样我可以帮助你。", + "speak": "你可以登录,这样我可以帮助你。" + }, + { + "text": "您需要登录才能采取进一步行动。", + "speak": "您需要登录才能采取进一步行动。" + } + ], + "inputHint": "acceptingInput" + }, + "AuthFailed": { + "replies": [ + { + "text": "你的身份验证失败,请再试一次。", + "speak": "你的身份验证失败,请再试一次。" + }, + { + "text": "你的登录失败,请稍后再试。", + "speak": "你的登录失败,请稍后再试。" + }, + { + "text": "你的登录失败了,让我们再试一次。", + "speak": "你的登录失败了,让我们再试一次。" + } + ], + "inputHint": "acceptingInput" + }, + "ActionEnded": { + "replies": [ + { + "text": "如果您需要我的帮助,请告诉我。", + "speak": "如果您需要我的帮助,请告诉我。" + }, + { + "text": "如果你需要我,我就在这里。", + "speak": "如果你需要我,我就在这里。" + } + ], + "inputHint": "acceptingInput" + }, + "CalendarErrorMessage": { + "replies": [ + { + "text": "对不起,看起来出了问题!", + "speak": "对不起,看起来出了问题!" + }, + { + "text": "发生错误,给我一些时间,稍后再试。", + "speak": "发生错误,给我一些时间,稍后再试。" + }, + { + "text": "出了点问题,对不起!", + "speak": "出了点问题,对不起!" + }, + { + "text": "我相信出了点问题。你以后可以再试一次吗?", + "speak": "我相信出了点问题。你以后可以再试一次吗?" + }, + { + "text": "对不起我觉得我现在找不到你想要的东西。请稍后再试。", + "speak": "对不起我觉得我现在找不到你想要的东西。请稍后再试。" + } + ], + "inputHint": "acceptingInput" + }, + "CalendarErrorMessageBotProblem": { + "replies": [ + { + "text": "对不起,出了点问题。开发人员已经收到通知并且在解决这个问题。你很快就又可以正常使用这个功能了。", + "speak": "对不起,出了点问题。开发人员已经收到通知并且在解决这个问题。你很快就又可以正常使用这个功能了。" + } + ], + "inputHint": "acceptingInput" + }, + "RetryInput": { + "replies": [ + { + "text": "对不起,我不明白你的意思。你可以再试一次吗?", + "speak": "对不起,我不明白你的意思。你可以再试一次吗?" + } + ], + "inputHint": "expectingInput" + } } diff --git a/skills/src/csharp/calendarskill/calendarskill/Utilities/Actions.cs b/skills/src/csharp/calendarskill/calendarskill/Utilities/Actions.cs index 8da85a1d6e..a13ee07b46 100644 --- a/skills/src/csharp/calendarskill/calendarskill/Utilities/Actions.cs +++ b/skills/src/csharp/calendarskill/calendarskill/Utilities/Actions.cs @@ -45,5 +45,7 @@ public static class Actions public const string ConfirmNumber = "ConfirmNumber"; public const string ShowRestParticipants = "ShowRestParticipants"; public const string AddMoreUserPrompt = "AddMoreUserPrompt"; + public const string FallbackEventPrompt = "fallbackEventPrompt"; + public const string RetryUnknown = "retryUnknown"; } } From 8cba2b8421a0c338386542b0736ef71c75c856e3 Mon Sep 17 00:00:00 2001 From: Qiong Wu Date: Tue, 30 Jul 2019 14:59:36 +0800 Subject: [PATCH 3/7] fix as comments --- .../Dialogs/MainDialog.cs | 24 +------------------ .../Services/SkillIntentRecognizer.cs | 19 ++++++++++++++- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs index b77d333bfb..c19ddd25fd 100644 --- a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs +++ b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs @@ -11,7 +11,6 @@ using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Dialogs; using Microsoft.Bot.Builder.Skills; -using Microsoft.Bot.Builder.Skills.Dialogs; using Microsoft.Bot.Builder.Skills.Models; using Microsoft.Bot.Builder.Solutions; using Microsoft.Bot.Builder.Solutions.Dialogs; @@ -24,7 +23,7 @@ namespace VirtualAssistantSample.Dialogs { - public class MainDialog : DispatchDialog + public class MainDialog : RouterDialog { private const string Location = "location"; private const string TimeZone = "timezone"; @@ -186,27 +185,6 @@ public MainDialog( } } - protected override async Task RedispatchAsync(DialogContext innerDc, DialogTurnResult result = null, CancellationToken cancellationToken = default(CancellationToken)) - { - var intent = result.Result as DispatchIntent; - - // Identify if the dispatch intent matches any Action within a Skill if so, we pass to the appropriate SkillDialog to hand-off - var identifiedSkill = SkillRouter.IsSkill(_settings.Skills, intent.Intent.ToString()); - - if (identifiedSkill != null) - { - // We have identiifed a skill so initialize the skill connection with the target skill - var dialogResult = await innerDc.BeginDialogAsync(identifiedSkill.Id); - - if (dialogResult.Status == DialogTurnStatus.Complete) - { - await CompleteAsync(innerDc); - } - } - - await base.RedispatchAsync(innerDc, result, cancellationToken); - } - protected override async Task OnEventAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { // Check if there was an action submitted from intro card diff --git a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Services/SkillIntentRecognizer.cs b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Services/SkillIntentRecognizer.cs index f311364718..ae61977295 100644 --- a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Services/SkillIntentRecognizer.cs +++ b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Services/SkillIntentRecognizer.cs @@ -32,7 +32,24 @@ public async Task RecognizeSkillIntentAsyncFunc(DialogContext dc) // Identify if the dispatch intent matches any action within a Skill if so, we pass to the appropriate SkillDialog to hand-off var recognizeSkill = SkillRouter.IsSkill(_settings.Skills, intent.ToString()); - return recognizeSkill?.Id; + + if (recognizeSkill == null) + { + if (intent == DispatchLuis.Intent.q_faq) + { + return "FAQ"; + } + else if (intent == DispatchLuis.Intent.q_chitchat) + { + return "Chit chat"; + } + } + else + { + return recognizeSkill.Id; + } + + return null; } public Func> RecognizeSkillIntentAsync { get { return RecognizeSkillIntentAsyncFunc; } } From 1de459ab7387865f4cfc1e03cf29677d335672ae Mon Sep 17 00:00:00 2001 From: Qiong Wu Date: Tue, 6 Aug 2019 10:33:36 +0800 Subject: [PATCH 4/7] update lib --- .../calendarskill/calendarskill/CalendarSkill.csproj | 9 ++------- .../src/csharp/emailskill/emailskill/EmailSkill.csproj | 9 ++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/skills/src/csharp/calendarskill/calendarskill/CalendarSkill.csproj b/skills/src/csharp/calendarskill/calendarskill/CalendarSkill.csproj index 30f94a7ded..ae9269f719 100644 --- a/skills/src/csharp/calendarskill/calendarskill/CalendarSkill.csproj +++ b/skills/src/csharp/calendarskill/calendarskill/CalendarSkill.csproj @@ -104,8 +104,8 @@ - - + + @@ -195,11 +195,6 @@ - - - - - True diff --git a/skills/src/csharp/emailskill/emailskill/EmailSkill.csproj b/skills/src/csharp/emailskill/emailskill/EmailSkill.csproj index 236bfdb16e..ea1603e2eb 100644 --- a/skills/src/csharp/emailskill/emailskill/EmailSkill.csproj +++ b/skills/src/csharp/emailskill/emailskill/EmailSkill.csproj @@ -44,8 +44,8 @@ - - + + @@ -179,11 +179,6 @@ - - - - - From 93c96d46c79353cc9f5a8628dbb614a683323f6b Mon Sep 17 00:00:00 2001 From: Qiong Wu Date: Tue, 6 Aug 2019 19:24:16 +0800 Subject: [PATCH 5/7] fix comments and upgrade to preview pkg --- skills/src/csharp/Skills.sln | 20 ----- .../calendarskill/Dialogs/SummaryDialog.cs | 79 +++++++++---------- .../VirtualAssistantSample.csproj | 9 +-- .../csharp/VirtualAssistantTemplate.sln | 20 ----- 4 files changed, 41 insertions(+), 87 deletions(-) diff --git a/skills/src/csharp/Skills.sln b/skills/src/csharp/Skills.sln index 1db9db44a2..c83979a609 100644 --- a/skills/src/csharp/Skills.sln +++ b/skills/src/csharp/Skills.sln @@ -37,10 +37,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WeatherSkill", "experimenta EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BingSearchSkill", "experimental\bingsearchskill\bingsearchskill\BingSearchSkill.csproj", "{8CB101FA-B496-4507-80A2-151FAB7E8ED1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Skills", "..\..\..\lib\csharp\microsoft.bot.builder.skills\Microsoft.Bot.Builder.Skills\Microsoft.Bot.Builder.Skills.csproj", "{B25E0652-3BCE-4EEE-86CB-F38660CC9736}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Solutions", "..\..\..\lib\csharp\microsoft.bot.builder.solutions\microsoft.bot.builder.solutions\Microsoft.Bot.Builder.Solutions.csproj", "{2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug - NuGet Packages|Any CPU = Debug - NuGet Packages|Any CPU @@ -161,22 +157,6 @@ Global {8CB101FA-B496-4507-80A2-151FAB7E8ED1}.Documentation|Any CPU.Build.0 = Debug|Any CPU {8CB101FA-B496-4507-80A2-151FAB7E8ED1}.Release|Any CPU.ActiveCfg = Release|Any CPU {8CB101FA-B496-4507-80A2-151FAB7E8ED1}.Release|Any CPU.Build.0 = Release|Any CPU - {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Debug - NuGet Packages|Any CPU.ActiveCfg = Debug - NuGet Packages|Any CPU - {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Debug - NuGet Packages|Any CPU.Build.0 = Debug - NuGet Packages|Any CPU - {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Documentation|Any CPU.Build.0 = Documentation|Any CPU - {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B25E0652-3BCE-4EEE-86CB-F38660CC9736}.Release|Any CPU.Build.0 = Release|Any CPU - {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Debug - NuGet Packages|Any CPU.ActiveCfg = Debug - NuGet Packages|Any CPU - {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Debug - NuGet Packages|Any CPU.Build.0 = Debug - NuGet Packages|Any CPU - {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Documentation|Any CPU.Build.0 = Documentation|Any CPU - {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2BBFC7CC-34F2-4D05-9DDE-99380E2E592E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/skills/src/csharp/calendarskill/calendarskill/Dialogs/SummaryDialog.cs b/skills/src/csharp/calendarskill/calendarskill/Dialogs/SummaryDialog.cs index 6a2f6542df..0039ec84ac 100644 --- a/skills/src/csharp/calendarskill/calendarskill/Dialogs/SummaryDialog.cs +++ b/skills/src/csharp/calendarskill/calendarskill/Dialogs/SummaryDialog.cs @@ -602,55 +602,54 @@ await sc.Context.SendActivityAsync(await GetOverviewMeetingListResponseAsync( if (state.FocusEvents.Count <= 0) { var currentList = GetCurrentPageMeetings(state.SummaryEvents, state); - if (state.UserSelectIndex < currentList.Count) + if (state.UserSelectIndex >= 0 && state.UserSelectIndex < currentList.Count) { state.FocusEvents.Add(currentList[state.UserSelectIndex]); } - else - { - return await sc.EndDialogAsync(); - } } - var focusEvent = state.FocusEvents.First(); - if (focusEvent.IsOrganizer) + if (state.FocusEvents != null && state.FocusEvents.Count > 0) { - if (topIntent == CalendarLuis.Intent.ChangeCalendarEntry) + var focusEvent = state.FocusEvents.First(); + if (focusEvent != null) { - state.Events.Add(focusEvent); - state.IsActionFromSummary = true; - return await sc.BeginDialogAsync(nameof(UpdateEventDialog), sc.Options); - } + if (focusEvent.IsOrganizer) + { + if (topIntent == CalendarLuis.Intent.ChangeCalendarEntry) + { + state.Events.Add(focusEvent); + state.IsActionFromSummary = true; + return await sc.BeginDialogAsync(nameof(UpdateEventDialog), sc.Options); + } - if (topIntent == CalendarLuis.Intent.DeleteCalendarEntry) - { - state.Events.Add(focusEvent); - state.IsActionFromSummary = true; - return await sc.BeginDialogAsync(nameof(ChangeEventStatusDialog), sc.Options); - } - } - else if (focusEvent.IsAccepted) - { - if (topIntent == CalendarLuis.Intent.DeleteCalendarEntry) - { - state.Events.Add(focusEvent); - state.IsActionFromSummary = true; - return await sc.BeginDialogAsync(nameof(ChangeEventStatusDialog), sc.Options); - } - } - else - { - if (topIntent == CalendarLuis.Intent.DeleteCalendarEntry || topIntent == CalendarLuis.Intent.AcceptEventEntry) - { - state.Events.Add(focusEvent); - state.IsActionFromSummary = true; - return await sc.BeginDialogAsync(nameof(ChangeEventStatusDialog), sc.Options); - } - } + if (topIntent == CalendarLuis.Intent.DeleteCalendarEntry) + { + state.Events.Add(focusEvent); + state.IsActionFromSummary = true; + return await sc.BeginDialogAsync(nameof(ChangeEventStatusDialog), sc.Options); + } + } + else if (focusEvent.IsAccepted) + { + if (topIntent == CalendarLuis.Intent.DeleteCalendarEntry) + { + state.Events.Add(focusEvent); + state.IsActionFromSummary = true; + return await sc.BeginDialogAsync(nameof(ChangeEventStatusDialog), sc.Options); + } + } + else + { + if (topIntent == CalendarLuis.Intent.DeleteCalendarEntry || topIntent == CalendarLuis.Intent.AcceptEventEntry) + { + state.Events.Add(focusEvent); + state.IsActionFromSummary = true; + return await sc.BeginDialogAsync(nameof(ChangeEventStatusDialog), sc.Options); + } + } - if (state.FocusEvents != null) - { - return await sc.BeginDialogAsync(Actions.Read, sc.Options); + return await sc.BeginDialogAsync(Actions.Read, sc.Options); + } } return await sc.ReplaceDialogAsync(Actions.RetryUnknown, sc.Options); diff --git a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/VirtualAssistantSample.csproj b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/VirtualAssistantSample.csproj index 012fd86ad5..5e7ca01125 100644 --- a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/VirtualAssistantSample.csproj +++ b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/VirtualAssistantSample.csproj @@ -22,8 +22,8 @@ - - + + @@ -34,11 +34,6 @@ - - - - - PublicResXFileCodeGenerator diff --git a/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln b/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln index b4475e5ec7..d79850104c 100644 --- a/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln +++ b/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln @@ -13,10 +13,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtualAssistantSample.Test EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualAssistantVSIX", "VSIX\VirtualAssistantVSIX.csproj", "{794F4E29-D65D-4F5F-9B04-55FFD5EE864D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Skills", "..\..\..\lib\csharp\microsoft.bot.builder.skills\Microsoft.Bot.Builder.Skills\Microsoft.Bot.Builder.Skills.csproj", "{8807EF9A-9974-4E7F-ADBD-B9E916039155}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Solutions", "..\..\..\lib\csharp\microsoft.bot.builder.solutions\microsoft.bot.builder.solutions\Microsoft.Bot.Builder.Solutions.csproj", "{988FB3D7-0251-4B0D-BA05-60B5DDF08743}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug - NuGet Packages|Any CPU = Debug - NuGet Packages|Any CPU @@ -49,22 +45,6 @@ Global {794F4E29-D65D-4F5F-9B04-55FFD5EE864D}.Documentation|Any CPU.Build.0 = Debug|Any CPU {794F4E29-D65D-4F5F-9B04-55FFD5EE864D}.Release|Any CPU.ActiveCfg = Release|Any CPU {794F4E29-D65D-4F5F-9B04-55FFD5EE864D}.Release|Any CPU.Build.0 = Release|Any CPU - {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Debug - NuGet Packages|Any CPU.ActiveCfg = Debug - NuGet Packages|Any CPU - {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Debug - NuGet Packages|Any CPU.Build.0 = Debug - NuGet Packages|Any CPU - {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Documentation|Any CPU.Build.0 = Documentation|Any CPU - {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8807EF9A-9974-4E7F-ADBD-B9E916039155}.Release|Any CPU.Build.0 = Release|Any CPU - {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Debug - NuGet Packages|Any CPU.ActiveCfg = Debug - NuGet Packages|Any CPU - {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Debug - NuGet Packages|Any CPU.Build.0 = Debug - NuGet Packages|Any CPU - {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Debug|Any CPU.Build.0 = Debug|Any CPU - {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Documentation|Any CPU.Build.0 = Documentation|Any CPU - {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Release|Any CPU.ActiveCfg = Release|Any CPU - {988FB3D7-0251-4B0D-BA05-60B5DDF08743}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 53075940fbbd4495aa0dbc584a586951efeb1001 Mon Sep 17 00:00:00 2001 From: Qiong Wu Date: Tue, 6 Aug 2019 20:15:41 +0800 Subject: [PATCH 6/7] fix comments --- lib/csharp/Directory.Build.props | 2 +- .../Sample/VirtualAssistantSample/Dialogs/MainDialog.cs | 1 - .../csharp/VirtualAssistantTemplate.sln | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/csharp/Directory.Build.props b/lib/csharp/Directory.Build.props index 52d2023641..a94dd79a72 100644 --- a/lib/csharp/Directory.Build.props +++ b/lib/csharp/Directory.Build.props @@ -8,7 +8,7 @@ - False + True diff --git a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs index df872ca329..1d133b17b3 100644 --- a/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs +++ b/templates/Virtual-Assistant-Template/csharp/Sample/VirtualAssistantSample/Dialogs/MainDialog.cs @@ -11,7 +11,6 @@ using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Dialogs; using Microsoft.Bot.Builder.Skills; -using Microsoft.Bot.Builder.Skills.Models; using Microsoft.Bot.Builder.Solutions; using Microsoft.Bot.Builder.Solutions.Dialogs; using Microsoft.Bot.Schema; diff --git a/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln b/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln index d79850104c..9a690c828f 100644 --- a/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln +++ b/templates/Virtual-Assistant-Template/csharp/VirtualAssistantTemplate.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.539 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29009.5 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VSIX", "VSIX", "{4FA953A9-9057-41A2-820D-6D07CA1206AE}" EndProject From d288c6196f2276e6e1d9c8eff2006858a9221da3 Mon Sep 17 00:00:00 2001 From: Qiong Wu Date: Thu, 8 Aug 2019 14:09:47 +0800 Subject: [PATCH 7/7] add doc --- docs/howto/skills/bestpractices.md | 48 +++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/docs/howto/skills/bestpractices.md b/docs/howto/skills/bestpractices.md index f87ab34d53..1849cfe5f9 100644 --- a/docs/howto/skills/bestpractices.md +++ b/docs/howto/skills/bestpractices.md @@ -425,4 +425,50 @@ For dialog state, you can save your data in `stepContext.State.Dialog[YOUR_DIALO ### Manage the dialogs -Use dialog options to transfer data among dialogs. Read [Create advanced conversation flow using branches and loops](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-dialog-manage-complex-conversation-flow?view=azure-bot-service-4.0&tabs=csharp) to learn more about dialog management. \ No newline at end of file +Use dialog options to transfer data among dialogs. Read [Create advanced conversation flow using branches and loops](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-dialog-manage-complex-conversation-flow?view=azure-bot-service-4.0&tabs=csharp) to learn more about dialog management. + +## Support skill fallback +Currently if you want to support skill switching scenarios like this in Virtual Assistant: + +- User: What's my meetings today? + +- Bot (Virtual Assistant, Calendar skill): [Meetings], do you want to hear the first one? + +- User: What tasks do I have? + +- Bot (Virtual Assistant): Are you sure to switch to todoSkill? + +- User: Yes, please. + +- Bot (Virtual Assistant, To Do skill): [To do list]. + +You can make this happen by sending the FallbackEvent back to Virtual Assistant, to confirm whether other skills are able to handle this utterance. + +```csharp +protected async Task SendFallback(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken)) + { + try + { + var state = await EmailStateAccessor.GetAsync(sc.Context); + + // Send Fallback Event + if (sc.Context.Adapter is EmailSkillWebSocketBotAdapter remoteInvocationAdapter) + { + await remoteInvocationAdapter.SendRemoteFallbackEventAsync(sc.Context, cancellationToken).ConfigureAwait(false); + + // Wait for the FallbackHandle event + return await sc.PromptAsync(Actions.FallbackEventPrompt, new PromptOptions()).ConfigureAwait(false); + } + + return await sc.NextAsync(); + } + catch (Exception ex) + { + await HandleDialogExceptions(sc, ex); + + return new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs); + } + } +``` + +If other skills can handle it, Virtual Assistant will cancel current skill and pass user input to the proper skill. If not, Virtual Assistant will send back a FallbackHandledEvent to continue current skill.