//Dirty hack to get reference to OnTurn in component start public BotWithLookup( IConfiguration configuration, ResourceExplorer resourceExplorer, ConversationState conversationState, UserState userState, SkillConversationIdFactoryBase skillConversationIdFactoryBase, LanguagePolicy languagePolicy, BotFrameworkAuthentication botFrameworkAuthentication = null, IBotTelemetryClient telemetryClient = null, IEnumerable <MemoryScope> scopes = default, IEnumerable <IPathResolver> pathResolvers = default, IEnumerable <Dialog> dialogs = default, ILogger logger = null) : base( configuration.GetSection("defaultRootDialog").Value, configuration.GetSection("defaultLg").Value ?? "main.lg", resourceExplorer, conversationState, userState, skillConversationIdFactoryBase, languagePolicy, botFrameworkAuthentication ?? BotFrameworkAuthenticationFactory.Create(), telemetryClient ?? new NullBotTelemetryClient(), scopes ?? Enumerable.Empty <MemoryScope>(), pathResolvers ?? Enumerable.Empty <IPathResolver>(), dialogs ?? Enumerable.Empty <Dialog>(), logger: logger ?? NullLogger <AdaptiveDialogBot> .Instance) { OnTurn = OnTurn ?? this.OnTurnAsync; }
/// <summary> /// Get the fall back locale from the optional locales. for example /// en-us, is a locale from English. But the option locales has [en, ''], /// So,en would be picked. /// </summary> /// <param name="locale">current locale.</param> /// <param name="optionalLocales">option locales.</param> /// <returns>the final locale.</returns> public static string FallbackLocale(string locale, IList <string> optionalLocales) { if (optionalLocales == null) { throw new ArgumentNullException(nameof(optionalLocales)); } if (optionalLocales.Contains(locale)) { return(locale); } var languagePolicy = new LanguagePolicy(); if (languagePolicy.ContainsKey(locale)) { var fallbackLocals = languagePolicy[locale]; foreach (var fallbackLocal in fallbackLocals) { if (optionalLocales.Contains(fallbackLocal)) { return(fallbackLocal); } } } else if (optionalLocales.Contains(string.Empty)) { return(string.Empty); } throw new Exception($"there is no locale fallback for {locale}"); }
public static Func <string, ImportResolverDelegate> MultiLanguageResolverDelegate(ResourceExplorer resourceExplorer) => (string targetLocale) => (string source, string id) => { var languagePolicy = new LanguagePolicy(); var locales = new string[] { string.Empty }; if (!languagePolicy.TryGetValue(targetLocale, out locales)) { if (!languagePolicy.TryGetValue(string.Empty, out locales)) { throw new Exception($"No supported language found for {targetLocale}"); } } var resourceName = Path.GetFileName(PathUtils.NormalizePath(id)); foreach (var locale in locales) { var resourceId = string.IsNullOrEmpty(locale) ? resourceName : resourceName.Replace(".lg", $".{locale}.lg"); if (resourceExplorer.TryGetResource(resourceId, out var resource)) { var content = resource.ReadTextAsync().GetAwaiter().GetResult(); return(content, resourceName); } } return(string.Empty, resourceName); };
/// <summary> /// find the common parent locale, for example /// en-us, en-gb, has the same parent locale: en. /// and en-us, fr, has the no same parent locale. /// </summary> /// <param name="locale1">first locale.</param> /// <param name="locale2">second locale.</param> /// <returns>the most closest common ancestor local.</returns> private static string FindCommonAncestorLocale(string locale1, string locale2) { var policy = new LanguagePolicy(); if (!policy.ContainsKey(locale1) || !policy.ContainsKey(locale2)) { return(string.Empty); } var key1Policy = policy[locale1]; var key2Policy = policy[locale2]; foreach (var key1Language in key1Policy) { foreach (var key2Language in key2Policy) { if (key1Language == key2Language) { return(key1Language); } } } return(string.Empty); }
/// <summary> /// Initializes a new instance of the <see cref="ConfigurationAdaptiveDialogBot"/> class using <see cref="IConfiguration"/>. /// </summary> /// <param name="configuration">An <see cref="IConfiguration"/> instance.</param> /// <param name="resourceExplorer">The Bot Builder <see cref="ResourceExplorer"/> to load the <see cref="AdaptiveDialog"/> from.</param> /// <param name="conversationState">The <see cref="ConversationState"/> implementation to use for this <see cref="AdaptiveDialog"/>.</param> /// <param name="userState">The <see cref="UserState"/> implementation to use for this <see cref="AdaptiveDialog"/>.</param> /// <param name="skillConversationIdFactoryBase">The <see cref="SkillConversationIdFactoryBase"/> implementation to use for this <see cref="AdaptiveDialog"/>.</param> /// <param name="languagePolicy">The <see cref="LanguagePolicy"/> implementation to use for this <see cref="AdaptiveDialog"/>.</param> /// <param name="botFrameworkAuthentication">A <see cref="BotFrameworkAuthentication"/> for making calls to Bot Builder Skills.</param> /// <param name="scopes">A set of <see cref="MemoryScope"/> that will be added to the <see cref="ITurnContext"/>.</param> /// <param name="pathResolvers">A set of <see cref="IPathResolver"/> that will be added to the <see cref="ITurnContext"/>.</param> /// <param name="dialogs">Custom <see cref="Dialog"/> that will be added to the root DialogSet.</param> /// <param name="logger">An <see cref="ILogger"/> instance.</param> public ConfigurationAdaptiveDialogBot( IConfiguration configuration, ResourceExplorer resourceExplorer, ConversationState conversationState, UserState userState, SkillConversationIdFactoryBase skillConversationIdFactoryBase, LanguagePolicy languagePolicy, BotFrameworkAuthentication botFrameworkAuthentication = null, IEnumerable <MemoryScope> scopes = default, IEnumerable <IPathResolver> pathResolvers = default, IEnumerable <Dialog> dialogs = default, ILogger logger = null) : base( configuration.GetSection(ConfigurationConstants.RootDialogKey).Value, configuration.GetSection(ConfigurationConstants.LanguageGeneratorKey).Value ?? DefaultLanguageGeneratorId, resourceExplorer, conversationState, userState, skillConversationIdFactoryBase, languagePolicy, botFrameworkAuthentication ?? BotFrameworkAuthenticationFactory.Create(), scopes ?? Enumerable.Empty <MemoryScope>(), pathResolvers ?? Enumerable.Empty <IPathResolver>(), dialogs ?? Enumerable.Empty <Dialog>(), logger: logger ?? NullLogger <AdaptiveDialogBot> .Instance) { }
public static Dictionary <string, IList <Resource> > GroupByLocale(ResourceExplorer resourceExplorer) { var resourceMapping = new Dictionary <string, IList <Resource> >(); var allResources = resourceExplorer.GetResources("lg"); var languagePolicy = new LanguagePolicy(); foreach (var item in languagePolicy) { var locale = item.Key; var suffixs = item.Value; var existNames = new HashSet <string>(); foreach (var suffix in suffixs) { if (string.IsNullOrEmpty(locale) || !string.IsNullOrEmpty(suffix)) { var resourcesWithSuchSuffix = allResources.Where(u => ParseLGFileName(u.Id).language == suffix); foreach (var resourceWithSuchSuffix in resourcesWithSuchSuffix) { var resourceName = resourceWithSuchSuffix.Id; var length = string.IsNullOrEmpty(suffix) ? 3 : 4; var prefixName = resourceName.Substring(0, resourceName.Length - suffix.Length - length); if (!existNames.Contains(prefixName)) { existNames.Add(prefixName); if (!resourceMapping.ContainsKey(locale)) { resourceMapping.Add(locale, new List <Resource> { resourceWithSuchSuffix }); } else { resourceMapping[locale].Add(resourceWithSuchSuffix); } } } } else { if (resourceMapping.ContainsKey(locale)) { var resourcesWithEmptySuffix = allResources.Where(u => ParseLGFileName(u.Id).language.Length == 0); foreach (var resourceWithEmptySuffix in resourcesWithEmptySuffix) { var resourceName = resourceWithEmptySuffix.Id; var prefixName = resourceName.Substring(0, resourceName.Length - 3); if (!existNames.Contains(prefixName)) { existNames.Add(prefixName); resourceMapping[locale].Add(resourceWithEmptySuffix); } } } } } } return(FallbackMultiLangResource(resourceMapping)); }
public async Task AdaptiveDialogBotExceptionWhenNoResource() { // Arrange var logger = NullLogger <AdaptiveDialogBot> .Instance; var storage = new MemoryStorage(); var conversationState = new ConversationState(storage); var userState = new UserState(storage); var skillConversationIdFactory = new SkillConversationIdFactory(storage); var languagePolicy = new LanguagePolicy("en-US"); var resourceExplorer = new ResourceExplorer(); var resourceProvider = new MockResourceProvider(resourceExplorer); resourceExplorer.AddResourceProvider(resourceProvider); var botFrameworkClientMock = new Mock <BotFrameworkClient>(); var botFrameworkAuthenticationMock = new Mock <BotFrameworkAuthentication>(); botFrameworkAuthenticationMock.Setup(bfa => bfa.CreateBotFrameworkClient()).Returns(botFrameworkClientMock.Object); // The test dialog being used here happens to not send anything so we only need to mock the type. var adapterMock = new Mock <BotAdapter>(); // ChannelId and Conversation.Id are required for ConversationState and // ChannelId and From.Id are required for UserState. var activity = new Activity { ChannelId = "test-channel", Conversation = new ConversationAccount { Id = "test-conversation-id" }, From = new ChannelAccount { Id = "test-id" } }; var turnContext = new TurnContext(adapterMock.Object, activity); // Act var bot = new AdaptiveDialogBot( "main.dialog", "main.lg", resourceExplorer, conversationState, userState, skillConversationIdFactory, languagePolicy, botFrameworkAuthenticationMock.Object, logger: logger); var exception = await Record.ExceptionAsync(() => ((IBot)bot).OnTurnAsync(turnContext, CancellationToken.None)); // Assert Assert.NotNull(exception); Assert.IsType <InvalidOperationException>(exception); }
/// <summary> /// Initializes a new instance of the <see cref="MultiLanguageLG"/> class. /// </summary> /// <param name="templatesPerLocale">Dictionary of LG file templates per locale.</param> /// <param name="defaultLanguage">Default language.</param> public MultiLanguageLG(Dictionary <string, Templates> templatesPerLocale, string defaultLanguage = "") { _lgPerLocale = new Dictionary <string, Templates>(StringComparer.OrdinalIgnoreCase); foreach (var templatesPair in templatesPerLocale) { _lgPerLocale.Add(templatesPair.Key, templatesPair.Value); } _languageFallbackPolicy = new LanguagePolicy(defaultLanguage); }
public void AdaptiveDialogBot_ShouldNotThrowOnNullLogger() { // Arrange var logger = NullLogger <AdaptiveDialogBot> .Instance; var storage = new MemoryStorage(); var conversationState = new ConversationState(storage); var userState = new UserState(storage); var skillConversationIdFactory = new SkillConversationIdFactory(storage); var languagePolicy = new LanguagePolicy("en-US"); var resourceExplorer = new ResourceExplorer(); var resourceProvider = new MockResourceProvider(resourceExplorer); resourceExplorer.AddResourceProvider(resourceProvider); var botFrameworkClientMock = new Mock <BotFrameworkClient>(); var botFrameworkAuthenticationMock = new Mock <BotFrameworkAuthentication>(); botFrameworkAuthenticationMock.Setup(bfa => bfa.CreateBotFrameworkClient()).Returns(botFrameworkClientMock.Object); // The test dialog being used here happens to not send anything so we only need to mock the type. var adapterMock = new Mock <BotAdapter>(); // ChannelId and Conversation.Id are required for ConversationState and // ChannelId and From.Id are required for UserState. var activity = new Activity { ChannelId = "test-channel", Conversation = new ConversationAccount { Id = "test-conversation-id" }, From = new ChannelAccount { Id = "test-id" } }; var turnContext = new TurnContext(adapterMock.Object, activity); var telemetryClient = new NullBotTelemetryClient(); new AdaptiveDialogBot( "main.dialog", "main.lg", resourceExplorer, conversationState, userState, skillConversationIdFactory, languagePolicy, botFrameworkAuthenticationMock.Object, telemetryClient, logger: null); }
public MultiLingualTemplateEngine(Dictionary <string, string> lgFilesPerLocale) { if (lgFilesPerLocale == null) { throw new ArgumentNullException(nameof(lgFilesPerLocale)); } foreach (KeyValuePair <string, string> filesPerLocale in lgFilesPerLocale) { TemplateEnginesPerLocale[filesPerLocale.Key] = Templates.ParseFile(filesPerLocale.Value); } LangFallBackPolicy = new LanguagePolicy(); }
/// <summary> /// Initializes a new instance of the <see cref="MultiLanguageLG"/> class. /// </summary> /// <param name="filePerLocale">Dictionary of locale and LG file.</param> /// <param name="defaultLanguage">Default language.</param> public MultiLanguageLG(Dictionary <string, string> filePerLocale, string defaultLanguage = "") { _lgPerLocale = new Dictionary <string, Templates>(StringComparer.OrdinalIgnoreCase); _languageFallbackPolicy = new LanguagePolicy(defaultLanguage); if (filePerLocale == null) { throw new ArgumentNullException(nameof(filePerLocale)); } foreach (var item in filePerLocale) { _lgPerLocale[item.Key] = Templates.ParseFile(item.Value); } }
/// <summary> /// Initializes a new instance of the <see cref="MultiLanguageLG"/> class. /// </summary> /// <param name="localeLGFiles">A dictionary of locale and LG file.</param> public MultiLanguageLG(Dictionary <string, string> localeLGFiles) { lgPerLocale = new Dictionary <string, Templates>(StringComparer.OrdinalIgnoreCase); languageFallbackPolicy = new LanguagePolicy(); if (localeLGFiles == null) { throw new ArgumentNullException(nameof(localeLGFiles)); } foreach (var filesPerLocale in localeLGFiles) { lgPerLocale[filesPerLocale.Key] = Templates.ParseFile(filesPerLocale.Value); } }
/// <summary> /// Initializes a new instance of the <see cref="LocaleTemplateEngineManager"/> class. /// </summary> /// <param name="localeLGFiles">A dictionary of locale and LG file(s).</param> /// <param name="fallbackLocale">The default fallback locale to use.</param> public LocaleTemplateEngineManager(Dictionary <string, List <string> > localeLGFiles, string fallbackLocale) { if (localeLGFiles == null) { throw new ArgumentNullException(nameof(localeLGFiles)); } if (string.IsNullOrEmpty(fallbackLocale)) { throw new ArgumentNullException(nameof(fallbackLocale)); } foreach (KeyValuePair <string, List <string> > filesPerLocale in localeLGFiles) { TemplateEnginesPerLocale[filesPerLocale.Key] = new TemplateEngine(); TemplateEnginesPerLocale[filesPerLocale.Key].AddFiles(filesPerLocale.Value); } languageFallbackPolicy = new LanguagePolicy(); localeDefault = fallbackLocale; }
public override async Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken = default, Dictionary <string, string> telemetryProperties = null, Dictionary <string, double> telemetryMetrics = null) { var policy = new List <string>(); if (LanguagePolicy.TryGetValue(activity.Locale, out string[] targetpolicy))
/// <summary> /// Starts the execution of the test sequence. /// </summary> /// <remarks>This methods sends the activities from the user to the bot and /// checks the responses from the bot based on the TestActions.</remarks> /// <param name="resourceExplorer">The resource explorer to use.</param> /// <param name="testName">Name of the test.</param> /// <param name="callback">The bot logic.</param> /// <param name="adapter">optional test adapter.</param> /// <param name="languagePolicy">The default language policy.</param> /// <returns>Runs the exchange between the user and the bot.</returns> public async Task ExecuteAsync(ResourceExplorer resourceExplorer, [CallerMemberName] string testName = null, BotCallbackHandler callback = null, TestAdapter adapter = null, LanguagePolicy languagePolicy = null) { if (adapter == null) { adapter = DefaultTestAdapter(resourceExplorer, testName); } adapter.EnableTrace = EnableTrace; adapter.Locale = Locale; adapter.Use(new MockHttpRequestMiddleware(HttpRequestMocks)); foreach (var userToken in UserTokenMocks) { userToken.Setup(adapter); } async Task Inspect(DialogContextInspector inspector) { var di = new DialogInspector(Dialog, resourceExplorer); var activity = new Activity(); activity.ApplyConversationReference(adapter.Conversation, isIncoming: true); activity.Type = "event"; activity.Name = "inspector"; await adapter.ProcessActivityAsync( activity, async (turnContext, cancellationToken) => await di.InspectAsync(turnContext, inspector).ConfigureAwait(false)).ConfigureAwait(false); } if (callback != null) { foreach (var testAction in Script) { await testAction.ExecuteAsync(adapter, callback, Inspect).ConfigureAwait(false); } } else { var dm = new DialogManager(Dialog) .UseResourceExplorer(resourceExplorer) .UseLanguageGeneration(); if (languagePolicy != null) { dm.UseLanguagePolicy(languagePolicy); } foreach (var testAction in Script) { await testAction.ExecuteAsync(adapter, dm.OnTurnAsync, Inspect).ConfigureAwait(false); } } }
public override async Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken) { if (!LanguagePolicy.TryGetValue(activity.Locale ?? string.Empty, out string[] policy))
public async Task AdaptiveDialogBotTurnState() { // Arrange var logger = NullLogger <AdaptiveDialogBot> .Instance; var storage = new MemoryStorage(); var conversationState = new ConversationState(storage); var userState = new UserState(storage); var skillConversationIdFactory = new SkillConversationIdFactory(storage); var languagePolicy = new LanguagePolicy("en-US"); var resourceExplorer = new ResourceExplorer(); var resourceProvider = new MockResourceProvider(resourceExplorer); resourceProvider.Add("main.dialog", new MockResource("{ \"$kind\": \"Microsoft.AdaptiveDialog\" }")); resourceExplorer.AddResourceProvider(resourceProvider); var botFrameworkClientMock = new Mock <BotFrameworkClient>(); var botFrameworkAuthenticationMock = new Mock <BotFrameworkAuthentication>(); botFrameworkAuthenticationMock.Setup(bfa => bfa.CreateBotFrameworkClient()).Returns(botFrameworkClientMock.Object); // The test dialog being used here happens to not send anything so we only need to mock the type. var adapterMock = new Mock <BotAdapter>(); // ChannelId and Conversation.Id are required for ConversationState and // ChannelId and From.Id are required for UserState. var activity = new Activity { ChannelId = "test-channel", Conversation = new ConversationAccount { Id = "test-conversation-id" }, From = new ChannelAccount { Id = "test-id" } }; var turnContext = new TurnContext(adapterMock.Object, activity); var telemetryClient = new NullBotTelemetryClient(); // Act var bot = new AdaptiveDialogBot( "main.dialog", "main.lg", resourceExplorer, conversationState, userState, skillConversationIdFactory, languagePolicy, botFrameworkAuthenticationMock.Object, telemetryClient, logger: logger); await bot.OnTurnAsync(turnContext, CancellationToken.None); // Assert Assert.NotNull(turnContext.TurnState.Get <BotFrameworkClient>()); Assert.NotNull(turnContext.TurnState.Get <SkillConversationIdFactoryBase>()); Assert.NotNull(turnContext.TurnState.Get <ConversationState>()); Assert.NotNull(turnContext.TurnState.Get <UserState>()); Assert.NotNull(turnContext.TurnState.Get <ResourceExplorer>()); Assert.NotNull(turnContext.TurnState.Get <LanguageGenerator>()); Assert.NotNull(turnContext.TurnState.Get <LanguageGeneratorManager>()); Assert.NotNull(turnContext.TurnState.Get <LanguagePolicy>()); }
public async Task AdaptiveDialogBotSetTestOptions() { // Arrange var logger = NullLogger <AdaptiveDialogBot> .Instance; var storage = new MemoryStorage(); var conversationState = new ConversationState(storage); var userState = new UserState(storage); var skillConversationIdFactory = new SkillConversationIdFactory(storage); var languagePolicy = new LanguagePolicy("en-US"); var resourceExplorer = new ResourceExplorer(); var resourceProvider = new MockResourceProvider(resourceExplorer); resourceProvider.Add("main.dialog", new MockResource("{ \"$kind\": \"Microsoft.AdaptiveDialog\" }")); resourceExplorer.AddResourceProvider(resourceProvider); var botFrameworkClientMock = new Mock <BotFrameworkClient>(); var botFrameworkAuthenticationMock = new Mock <BotFrameworkAuthentication>(); botFrameworkAuthenticationMock.Setup(bfa => bfa.CreateBotFrameworkClient()).Returns(botFrameworkClientMock.Object); // The test dialog being used here happens to not send anything so we only need to mock the type. var adapterMock = new Mock <BotAdapter>(); // Type "event" and Name of "SetTestOptions" should store Value in ConversationState. // ChannelId and Conversation.Id are required for ConversationState and // ChannelId and From.Id are required for UserState. var activity = new Activity { Type = "event", Name = "SetTestOptions", ChannelId = "test-channel", Conversation = new ConversationAccount { Id = "test-conversation-id" }, From = new ChannelAccount { Id = "test-id" }, Value = new JObject { { "randomSeed", new JValue(123) }, { "randomValue", new JValue(456) } } }; var turnContext = new TurnContext(adapterMock.Object, activity); var telemetryClient = new NullBotTelemetryClient(); // Act var bot = new AdaptiveDialogBot( "main.dialog", "main.lg", resourceExplorer, conversationState, userState, skillConversationIdFactory, languagePolicy, botFrameworkAuthenticationMock.Object, telemetryClient, logger: logger); await bot.OnTurnAsync(turnContext, CancellationToken.None); // Assert TestOptions are in Conversation var testOptionsAccessor = conversationState.CreateProperty <JObject>("TestOptions"); Assert.Equal(123, (await testOptionsAccessor.GetAsync(turnContext)).GetValue("randomSeed")); Assert.Equal(456, (await testOptionsAccessor.GetAsync(turnContext)).GetValue("randomValue")); }
public Task <RecognizerResult> RecognizeAsync(ITurnContext turnContext, CancellationToken cancellationToken) { if (!LanguagePolicy.TryGetValue(turnContext.Activity.Locale ?? string.Empty, out string[] policy))
public static async Task RunTestScript(ResourceExplorer resourceExplorer, string resourceId = null, IConfiguration configuration = null, [CallerMemberName] string testName = null, LanguagePolicy languagePolicy = null) { var script = resourceExplorer.LoadType <TestScript>(resourceId ?? $"{testName}.test.dialog"); script.Configuration = configuration ?? new ConfigurationBuilder().AddInMemoryCollection().Build(); script.Description = script.Description ?? resourceId; await script.ExecuteAsync(testName : testName, resourceExplorer : resourceExplorer, languagePolicy : languagePolicy).ConfigureAwait(false); }
public async Task MultiLanguageRecognizerTest_LanguagePolicy() { var languagePolicy = new LanguagePolicy("en-gb"); await TestUtils.RunTestScript(_resourceExplorerFixture.ResourceExplorer, languagePolicy : languagePolicy); }