示例#1
0
	public void StartConversation( Topic[] topics )
	{
		// Verify topics we gave us aren't bunk
		// need to have a start topic
		// and the start topic needs to have options
		Topic start = null;

		foreach ( Topic topic in topics )
		{
			if ( topic._topicName == TopicName.START )
			{
				start = topic;
				break;
			}
		}

		if ( start == null )
		{
			Debug.LogError("Topics don't contain a START topic!");
			return;
		}

		_state = new ConversationState
		{ 
			_topics = topics,
			_currentTopicName = TopicName.START,
			_currentTopic = start
		};

		OnConversationStart();
	}
示例#2
0
	// Player Responded, set the next topic
	public void ChooseOption( ConversationOption option )
	{
		TopicName next_topic_name = option._nextTopic;

		// Special Handling for END
		if ( next_topic_name == TopicName.END )
		{
			option.OnOptionChosen();

			// End Topic
			OnConversationEnd();
			_state = null;
			return;
		}

		// don't do anything, just a warning, if the topic they chose doesn't exist as a valid option
		bool found = false;
		foreach ( ConversationOption curr_option in _state._currentTopic._options )
		{
			if ( curr_option == option )
			{
				found = true;
				break;
			}
		}

		if ( ! found )
		{
			Debug.LogError("TOPIC IS NOT A VALID OPTION: " + next_topic_name);
			return;
		}

		// Make sure there is a mapping to this topic name in our topics collection
		Topic next_topic = null;

		foreach ( Topic topic in _state._topics )
		{
			if ( topic._topicName == next_topic_name )
			{
				next_topic = topic;
				break;
			}
		}

		if ( next_topic == null )
		{
			Debug.LogError("FAILED TO FIND FIND TOPIC IN TOPIC NAME: " + next_topic_name );
			return;
		}

		// Trigger Event
		option.OnOptionChosen();

		// Update State
		_state._currentTopicName = next_topic_name;
		_state._currentTopic = next_topic;

		_topicChanged.Invoke();
	} 
示例#3
0
        public ConversationContext RunStep(ConversationState state, string message)
        {
            if (state.ConversationStep > Steps.Count) throw new ArgumentOutOfRangeException("stepNumber");

            var result = Steps[state.ConversationStep - 1].Execute(state, message);

            return result;
        }
示例#4
0
文件: Chatbot.cs 项目: GGulati/IRCBot
        private void ChangeBot(string user, ChatterBotType type)
        {
            user = user.ToLower();

            if (!conversations.ContainsKey(user))
                conversations.Add(user, new ConversationState(this, type));
            else
                conversations[user] = new ConversationState(this, type);
        }
 public void Close()
 {
     CheckState(ConversationState.Opened);
     foreach(ISessionFactory sessionFactory in _map.Keys.ToArray())
     {
         _map[sessionFactory].Close();
         _map[sessionFactory].Dispose();
         _map[sessionFactory] = null;
     }
     _state = ConversationState.Closed;
 }
示例#6
0
 public override void Load(System.Xml.XmlReader reader)
 {
     while (reader.Read())
     {
         if (reader.MoveToContent() == System.Xml.XmlNodeType.Element)
         {
             if (reader.Name == "ConversationState")
             {
                 string user = reader.GetAttribute("user");
                 var state = new ConversationState(this, (ChatterBotType)Enum.Parse(typeof(ChatterBotType), reader.GetAttribute("type")));
                 conversations.Add(user, state);
             }
         }
     }
 }
        public async Task ConfirmPrompt_Locale_Override_ChoiceDefaults(string defaultLocale, string prompt, string utterance, string expectedResponse)
        {
            var convoState  = new ConversationState(new MemoryStorage());
            var dialogState = convoState.CreateProperty <DialogState>("dialogState");

            var adapter = new TestAdapter()
                          .Use(new AutoSaveStateMiddleware(convoState));

            // Create new DialogSet.
            var dialogs = new DialogSet(dialogState);

            var culture = new PromptCultureModel()
            {
                InlineOr      = " customOr ",
                InlineOrMore  = " customOrMore ",
                Locale        = "custom-custom",
                Separator     = "customSeparator",
                NoInLanguage  = "customNo",
                YesInLanguage = "customYes",
            };

            var customDict = new Dictionary <string, (Choice, Choice, ChoiceFactoryOptions)>()
            {
                { culture.Locale, (new Choice(culture.YesInLanguage), new Choice(culture.NoInLanguage), new ChoiceFactoryOptions(culture.Separator, culture.InlineOr, culture.InlineOrMore, true)) },
            };

            // Prompt should default to English if locale is a non-supported value
            dialogs.Add(new ConfirmPrompt("ConfirmPrompt", customDict, null, defaultLocale));

            await new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                turnContext.Activity.Locale = culture.Locale;

                var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken);

                var results = await dc.ContinueDialogAsync(cancellationToken);
                if (results.Status == DialogTurnStatus.Empty)
                {
                    await dc.PromptAsync("ConfirmPrompt", new PromptOptions {
                        Prompt = new Activity {
                            Type = ActivityTypes.Message, Text = "Prompt."
                        }
                    }, cancellationToken);
                }
                else if (results.Status == DialogTurnStatus.Complete)
                {
                    if ((bool)results.Result)
                    {
                        await turnContext.SendActivityAsync(MessageFactory.Text("1"), cancellationToken);
                    }
                    else
                    {
                        await turnContext.SendActivityAsync(MessageFactory.Text("0"), cancellationToken);
                    }
                }
            })
            .Send("hello")
            .AssertReply("Prompt. " + prompt)
            .Send(utterance)
            .AssertReply(expectedResponse)
            .StartTestAsync();
        }
示例#8
0
 public SampleBot(IConfiguration configuration, ConversationState conversationState)
 {
     Configuration          = configuration;
     this.conversationState = conversationState;
     dialog = new BasicDialog(conversationState);
 }
示例#9
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson();

            services.AddSingleton<IConfiguration>(this.Configuration);

            // Load settings
            var settings = new BotSettings();
            Configuration.Bind(settings);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton<ICredentialProvider, ConfigurationCredentialProvider>();
            services.AddSingleton<BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService<IBotFrameworkHttpAdapter>());

            // Register AuthConfiguration to enable custom claim validation for skills.
            services.AddSingleton(sp => new AuthenticationConfiguration { ClaimsValidator = new AllowedCallersClaimsValidator(settings.SkillConfiguration) });

            // register components.
            ComponentRegistration.Add(new DialogsComponentRegistration());
            ComponentRegistration.Add(new DeclarativeComponentRegistration());
            ComponentRegistration.Add(new AdaptiveComponentRegistration());
            ComponentRegistration.Add(new LanguageGenerationComponentRegistration());
            ComponentRegistration.Add(new QnAMakerComponentRegistration());
            ComponentRegistration.Add(new LuisComponentRegistration());

            // This is for custom action component registration.
            //ComponentRegistration.Add(new CustomActionComponentRegistration());

            // Register the skills client and skills request handler.
            services.AddSingleton<SkillConversationIdFactoryBase, SkillConversationIdFactory>();
            services.AddHttpClient<BotFrameworkClient, SkillHttpClient>();
            services.AddSingleton<ChannelServiceHandler, SkillHandler>();

            // Register telemetry client, initializers and middleware
            services.AddApplicationInsightsTelemetry(settings?.ApplicationInsights?.InstrumentationKey ?? string.Empty);

            services.AddSingleton<ITelemetryInitializer, OperationCorrelationTelemetryInitializer>();
            services.AddSingleton<ITelemetryInitializer, TelemetryBotIdInitializer>();
            services.AddSingleton<IBotTelemetryClient, BotTelemetryClient>();
            services.AddSingleton<TelemetryLoggerMiddleware>(sp =>
            {
                var telemetryClient = sp.GetService<IBotTelemetryClient>();
                return new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: settings?.Telemetry?.LogPersonalInformation ?? false);
            });
            services.AddSingleton<TelemetryInitializerMiddleware>(sp =>
            {
                var httpContextAccessor = sp.GetService<IHttpContextAccessor>();
                var telemetryLoggerMiddleware = sp.GetService<TelemetryLoggerMiddleware>();
                return new TelemetryInitializerMiddleware(httpContextAccessor, telemetryLoggerMiddleware, settings?.Telemetry?.LogActivities ?? false);
            });

            var storage = ConfigureStorage(settings);

            services.AddSingleton(storage);
            var userState = new UserState(storage);
            var conversationState = new ConversationState(storage);
            services.AddSingleton(userState);
            services.AddSingleton(conversationState);

            // Configure bot loading path
            var botDir = settings.Bot;
            var resourceExplorer = new ResourceExplorer().AddFolder(botDir);
            var rootDialog = GetRootDialog(botDir);

            var defaultLocale = Configuration.GetValue<string>("defaultLanguage") ?? "en-us";

            services.AddSingleton(resourceExplorer);

            resourceExplorer.RegisterType<OnQnAMatch>("Microsoft.OnQnAMatch");

            services.AddSingleton<IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>(s =>
                GetBotAdapter(storage, settings, userState, conversationState, s));

            var removeRecipientMention = settings?.Feature?.RemoveRecipientMention ?? false;

            services.AddSingleton<IBot>(s =>
                new ComposerBot(
                    s.GetService<ConversationState>(),
                    s.GetService<UserState>(),
                    s.GetService<ResourceExplorer>(),
                    s.GetService<BotFrameworkClient>(),
                    s.GetService<SkillConversationIdFactoryBase>(),
                    s.GetService<IBotTelemetryClient>(),
                    rootDialog,
                    defaultLocale,
                    removeRecipientMention));
        }
示例#10
0
文件: Startup.cs 项目: mbyase/AI
        public void ConfigureServices(IServiceCollection services)
        {
            // Load the connected services from .bot file.
            var botFilePath   = Configuration.GetSection("botFilePath")?.Value;
            var botFileSecret = Configuration.GetSection("botFileSecret")?.Value;
            var botConfig     = BotConfiguration.Load(botFilePath ?? @".\EmailSkill.bot", botFileSecret);

            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded."));

            // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection.
            var parameters         = Configuration.GetSection("Parameters")?.Get <string[]>();
            var configuration      = Configuration.GetSection("Configuration")?.GetChildren()?.ToDictionary(x => x.Key, y => y.Value as object);
            var supportedProviders = Configuration.GetSection("SupportedProviders")?.Get <string[]>();
            ISkillConfiguration connectedServices = new SkillConfiguration(botConfig, supportedProviders, parameters, configuration);

            services.AddSingleton(sp => connectedServices);

            var defaultLocale = Configuration.GetSection("defaultLocale").Get <string>();

            // Initialize Bot State
            var cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file.");
            var cosmosDb        = cosmosDbService as CosmosDbService;
            var cosmosOptions   = new CosmosDbStorageOptions()
            {
                CosmosDBEndpoint = new Uri(cosmosDb.Endpoint),
                AuthKey          = cosmosDb.Key,
                CollectionId     = cosmosDb.Collection,
                DatabaseId       = cosmosDb.Database,
            };
            var dataStore         = new CosmosDbStorage(cosmosOptions);
            var userState         = new UserState(dataStore);
            var conversationState = new ConversationState(dataStore);

            services.AddSingleton(dataStore);
            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(new BotStateSet(userState, conversationState));

            // Initialize Email client
            services.AddSingleton <IServiceManager, ServiceManager>();

            // Add the bot with options
            services.AddBot <EmailSkill>(options =>
            {
                // Load the connected services from .bot file.
                var environment = _isProduction ? "production" : "development";
                var service     = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment);
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }

                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Telemetry Middleware (logs activity messages in Application Insights)
                var appInsightsService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.AppInsights) ?? throw new Exception("Please configure your AppInsights connection in your .bot file.");
                var instrumentationKey = (appInsightsService as AppInsightsService).InstrumentationKey;
                var appInsightsLogger  = new TelemetryLoggerMiddleware(instrumentationKey, logUserName: true, logOriginalMessage: true);
                options.Middleware.Add(appInsightsLogger);

                // Catches any errors that occur during a conversation turn and logs them to AppInsights.
                options.OnTurnError = async(context, exception) =>
                {
                    await context.SendActivityAsync(context.Activity.CreateReply(EmailSharedResponses.EmailErrorMessage));
                    await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Email Skill Error: {exception.Message} | {exception.StackTrace}"));
                    connectedServices.TelemetryClient?.TrackException(exception);
                };

                // Transcript Middleware (saves conversation history in a standard format)
                var storageService       = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file.");
                var blobStorage          = storageService as BlobStorageService;
                var transcriptStore      = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container);
                var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore);
                options.Middleware.Add(transcriptMiddleware);

                // Typing Middleware (automatically shows typing when the bot is responding/working)
                var typingMiddleware = new ShowTypingMiddleware();
                options.Middleware.Add(typingMiddleware);
                options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en-us"));
                options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState));
            });
        }
 public DialogAndWelcomeBot(ConversationState conversationState, UserState userState, T dialog, ILogger <DialogBot <T> > logger)
     : base(conversationState, userState, dialog, logger)
 {
 }
示例#12
0
 public CitaIMQBotAccessors(ConversationState conversationState, UserState userState)
 {
     ConversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
     UserState         = userState ?? throw new ArgumentNullException(nameof(userState));
 }
        public SkillAdapterWithErrorHandler(IConfiguration configuration, ICredentialProvider credentialProvider, AuthenticationConfiguration authConfig, ILogger <BotFrameworkHttpAdapter> logger, ConversationState conversationState)
            : base(configuration, credentialProvider, authConfig, logger: logger)
        {
            _conversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
            _logger            = logger ?? throw new ArgumentNullException(nameof(logger));
            OnTurnError        = HandleTurnError;

            // Add autosave middleware for SSO.
            Use(new SsoSaveStateMiddleware(_conversationState));
        }
示例#14
0
        public AdapterWithErrorHandler(IConfiguration configuration, ILogger <BotFrameworkHttpAdapter> logger, ConversationState conversationState = null)
            : base(configuration, logger)
        {
            OnTurnError = async(turnContext, exception) =>
            {
                // Log any leaked exception from the application.
                logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");

                // Send a message to the user
                await turnContext.SendActivityAsync("The bot encounted an error or bug.");

                await turnContext.SendActivityAsync("To run this sample make sure you have the LUIS and QnA models deployed.");

                await turnContext.SendActivityAsync("To continue to run this bot, please fix the bot source code.");

                if (conversationState != null)
                {
                    try
                    {
                        // Delete the conversationState for the current conversation to prevent the
                        // bot from getting stuck in a error-loop caused by being in a bad state.
                        // ConversationState should be thought of as similar to "cookie-state" in a Web pages.
                        await conversationState.DeleteAsync(turnContext);
                    }
                    catch (Exception e)
                    {
                        logger.LogError(e, $"Exception caught on attempting to Delete ConversationState : {e.Message}");
                    }
                }

                // Send a trace activity, which will be displayed in the Bot Framework Emulator
                await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError");
            };
        }
示例#15
0
 public test(ConversationState conversationState, UserState userState)
 {
     _conversationState = conversationState;
     _userState         = userState;
 }
 public NHibernateConversation(IDictionary<ISessionFactory, ISession> map)
 {
     _map = map;
     _state = ConversationState.Opened;
 }
示例#17
0
        public AdapterWithErrorHandler(IConfiguration configuration, ILogger <BotFrameworkHttpAdapter> logger, ConversationState conversationState = null, SkillHttpClient skillClient = null, SkillsConfiguration skillsConfig = null)
            : base(configuration, logger)
        {
            _configuration     = configuration ?? throw new ArgumentNullException(nameof(configuration));
            _conversationState = conversationState;
            _logger            = logger ?? throw new ArgumentNullException(nameof(logger));
            _skillClient       = skillClient;
            _skillsConfig      = skillsConfig;

            OnTurnError = HandleTurnError;
        }
示例#18
0
        public async void RecognizeTest()
        {
            // arrage
            var expectedAnswer = "answer";
            var expectedScore  = 100;
            var expectedId     = 10;

            List <Metadata> metadata = new List <Metadata>();

            metadata.Add(new Metadata()
            {
                Name = "sample", Value = "value"
            });

            List <string> questions = new List <string>();

            questions.Add("hello");

            List <QueryResult> listQueryResults = new List <QueryResult>();

            listQueryResults.Add(new QueryResult()
            {
                Id        = expectedId,
                Answer    = expectedAnswer,
                Score     = expectedScore,
                Metadata  = metadata.ToArray(),
                Questions = questions.ToArray()
            });

            QueryResults queryResults = new QueryResults();

            queryResults.Answers = listQueryResults.ToArray();

            var jsonRecognizerResult = JsonConvert.SerializeObject(queryResults);

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock
            .Protected()
            .Setup <Task <HttpResponseMessage> >(
                "SendAsync",
                ItExpr.IsAny <HttpRequestMessage>(),
                ItExpr.IsAny <CancellationToken>()
                )
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content    = new StringContent(jsonRecognizerResult),
            })
            .Verifiable();

            var httpClient = new HttpClient(handlerMock.Object)
            {
                BaseAddress = new Uri("http://localhost/")
            };
            var storage           = new MemoryStorage();
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);
            var adapter           = new TestAdapter().Use(new AutoSaveStateMiddleware(conversationState));
            var dialogState       = conversationState.CreateProperty <DialogState>("dialogState");
            var dialogs           = new DialogSet(dialogState);
            var steps             = new WaterfallStep[]
            {
                async(step, cancellationToken) =>
                {
                    await step.Context.SendActivityAsync("response");

                    // act
                    IQnAMakerService qnAMakerService = new QnAMakerService(httpClient, EnvironmentName, ContentRootPath);
                    var result = await qnAMakerService.QnAMakerServices["name"].GetAnswersAsync(step.Context);
                    var item   = result.FirstOrDefault();

                    // assert
                    Assert.Equal(expectedId, item.Id);
                    Assert.Equal(expectedAnswer, item.Answer);
                    Assert.Equal(expectedScore / 100, item.Score);

                    return(Dialog.EndOfTurn);
                }
            };

            dialogs.Add(new WaterfallDialog(
                            "test",
                            steps));

            await new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken);
                await dc.ContinueDialogAsync(cancellationToken);
                if (!turnContext.Responded)
                {
                    await dc.BeginDialogAsync("test", null, cancellationToken);
                }
            })
            .Send("ask")
            .AssertReply("response")
            .StartTestAsync();
        }
示例#19
0
        public void ConfigureServices(IServiceCollection services)
        {
            // Load the connected services from .bot file.
            var botFilePath   = Configuration.GetSection("botFilePath")?.Value;
            var botFileSecret = Configuration.GetSection("botFileSecret")?.Value;
            var botConfig     = BotConfiguration.Load(botFilePath ?? @".\$safeprojectname$.bot", botFileSecret);

            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded."));

            // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection.
            var connectedServices = new BotServices(botConfig);

            services.AddSingleton(sp => connectedServices);

            // Initialize Bot State
            var cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file.");
            var cosmosDb        = cosmosDbService as CosmosDbService;
            var cosmosOptions   = new CosmosDbStorageOptions()
            {
                CosmosDBEndpoint = new Uri(cosmosDb.Endpoint),
                AuthKey          = cosmosDb.Key,
                CollectionId     = cosmosDb.Collection,
                DatabaseId       = cosmosDb.Database,
            };
            var dataStore         = new CosmosDbStorage(cosmosOptions);
            var userState         = new UserState(dataStore);
            var conversationState = new ConversationState(dataStore);

            services.AddSingleton(dataStore);
            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(new BotStateSet(userState, conversationState));

            // Add the bot with options
            services.AddBot <$safeprojectname$>(options =>
            {
                // Load the connected services from .bot file.
                var environment = _isProduction ? "production" : "development";
                var service     = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment);
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }

                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Telemetry Middleware (logs activity messages in Application Insights)
                var appInsightsService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.AppInsights) ?? throw new Exception("Please configure your AppInsights connection in your .bot file.");
                var instrumentationKey = (appInsightsService as AppInsightsService).InstrumentationKey;
                var appInsightsLogger  = new TelemetryLoggerMiddleware(instrumentationKey, logUserName: true, logOriginalMessage: true);
                options.Middleware.Add(appInsightsLogger);

                // Catches any errors that occur during a conversation turn and logs them to AppInsights.
                options.OnTurnError = async(context, exception) =>
                {
                    await context.SendActivityAsync("Sorry, it looks like something went wrong.");
                    connectedServices.TelemetryClient.TrackException(exception);
                };

                // Transcript Middleware (saves conversation history in a standard format)
                var storageService       = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file.");
                var blobStorage          = storageService as BlobStorageService;
                var transcriptStore      = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container);
                var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore);
                options.Middleware.Add(transcriptMiddleware);

                // Typing Middleware (automatically shows typing when the bot is responding/working)
                var typingMiddleware = new ShowTypingMiddleware();
                options.Middleware.Add(typingMiddleware);

                options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState));
            });
        }
示例#20
0
        public JoinEventDialog(
            BotSettings settings,
            BotServices services,
            ConversationState conversationState,
            LocaleTemplateEngineManager localeTemplateEngineManager,
            IServiceManager serviceManager,
            IBotTelemetryClient telemetryClient,
            MicrosoftAppCredentials appCredentials)
            : base(nameof(JoinEventDialog), settings, services, conversationState, localeTemplateEngineManager, serviceManager, telemetryClient, appCredentials)
        {
            TelemetryClient = telemetryClient;

            var joinMeeting = new WaterfallStep[]
            {
                GetAuthToken,
                AfterGetAuthToken,
                CheckFocusedEvent,
                ConfirmNumber,
                AfterConfirmNumber
            };

            var findEvent = new WaterfallStep[]
            {
                SearchEventsWithEntities,
                GetEvents,
                AddConflictFlag,
                ChooseEvent
            };

            var getEvents = new WaterfallStep[]
            {
                GetEventsPrompt,
                AfterGetEventsPrompt,
                CheckValid,
            };

            var chooseEvent = new WaterfallStep[]
            {
                ChooseEventPrompt,
                AfterChooseEvent
            };

            AddDialog(new WaterfallDialog(Actions.ConnectToMeeting, joinMeeting)
            {
                TelemetryClient = telemetryClient
            });
            AddDialog(new WaterfallDialog(Actions.GetEvents, getEvents)
            {
                TelemetryClient = telemetryClient
            });
            AddDialog(new WaterfallDialog(Actions.FindEvent, findEvent)
            {
                TelemetryClient = telemetryClient
            });
            AddDialog(new WaterfallDialog(Actions.ChooseEvent, chooseEvent)
            {
                TelemetryClient = telemetryClient
            });

            // Set starting dialog for component
            InitialDialogId = Actions.ConnectToMeeting;
        }
示例#21
0
 public BeerBot(ConversationState conversationState, UserState userState)
 {
     _conversationState = conversationState;
     _userState         = userState;
 }
示例#22
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection"/> specifies the contract for a collection of service descriptors.</param>
        /// <seealso cref="IStatePropertyAccessor{T}"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/>
        public void ConfigureServices(IServiceCollection services)
        {
            var secretKey   = Configuration.GetSection("botFileSecret")?.Value;
            var botFilePath = Configuration.GetSection("botFilePath")?.Value;

            if (!File.Exists(botFilePath))
            {
                throw new FileNotFoundException($"The .bot configuration file was not found. botFilePath: {botFilePath}");
            }

            // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
            BotConfiguration botConfig = null;

            try
            {
                botConfig = BotConfiguration.Load(botFilePath, secretKey);
            }
            catch
            {
                var msg = @"Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment.
        - You can find the botFilePath and botFileSecret in the Azure App Service application settings.
        - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret.
        - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration.
        ";
                throw new InvalidOperationException(msg);
            }

            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot configuration file could not be loaded. botFilePath: {botFilePath}"));

            // Retrieve current endpoint.
            var environment = _isProduction ? "production" : "development";
            var service     = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment);

            if (service == null && _isProduction)
            {
                // Attempt to load development environment
                service = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == "development").FirstOrDefault();
            }

            if (!(service is EndpointService endpointService))
            {
                throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
            }

            // Memory Storage is for local bot debugging only. When the bot
            // is restarted, everything stored in memory will be gone.
            IStorage dataStore = new MemoryStorage();

            // For production bots use the Azure Blob or
            // Azure CosmosDB storage providers. For the Azure
            // based storage providers, add the Microsoft.Bot.Builder.Azure
            // Nuget package to your solution. That package is found at:
            // https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/
            // Un-comment the following lines to use Azure Blob Storage
            // // Storage configuration name or ID from the .bot file.
            // const string StorageConfigurationId = "<STORAGE-NAME-OR-ID-FROM-BOT-FILE>";
            // var blobConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId);
            // if (!(blobConfig is BlobStorageService blobStorageConfig))
            // {
            //    throw new InvalidOperationException($"The .bot file does not contain an blob storage with name '{StorageConfigurationId}'.");
            // }
            // // Default container name.
            // const string DefaultBotContainer = "<DEFAULT-CONTAINER>";
            // var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? DefaultBotContainer : blobStorageConfig.Container;
            // IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer);

            // Create and add conversation state.
            var conversationState = new ConversationState(dataStore);

            services.AddSingleton(conversationState);

            services.AddBot <$safeprojectname$Bot> (options =>
            {
                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Catches any errors that occur during a conversation turn and logs them to currently
                // configured ILogger.
                ILogger logger = _loggerFactory.CreateLogger <$safeprojectname$Bot>();

                options.OnTurnError = async(context, exception) =>
                {
                    logger.LogError($"Exception caught : {exception}");
                    await context.SendActivityAsync("Sorry, it looks like something went wrong.");
                };
            });
        }
示例#23
0
        /// <summary>
        /// Runs dialog system in the context of an ITurnContext.
        /// </summary>
        /// <param name="context">turn context.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>result of the running the logic against the activity.</returns>
        public async Task <DialogManagerResult> OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default)
        {
            var botStateSet = new BotStateSet();

            // Preload TurnState with DM TurnState.
            foreach (var pair in InitialTurnState)
            {
                context.TurnState.Set(pair.Key, pair.Value);
            }

            // register DialogManager with TurnState.
            context.TurnState.Set(this);

            if (ConversationState == null)
            {
                ConversationState = context.TurnState.Get <ConversationState>() ?? throw new InvalidOperationException($"Unable to get an instance of {nameof(ConversationState)} from turnContext.");
            }
            else
            {
                context.TurnState.Set(ConversationState);
            }

            botStateSet.Add(ConversationState);

            if (UserState == null)
            {
                UserState = context.TurnState.Get <UserState>();
            }
            else
            {
                context.TurnState.Set(UserState);
            }

            if (UserState != null)
            {
                botStateSet.Add(UserState);
            }

            // create property accessors
            var lastAccessProperty = ConversationState.CreateProperty <DateTime>(LastAccess);
            var lastAccess         = await lastAccessProperty.GetAsync(context, () => DateTime.UtcNow, cancellationToken).ConfigureAwait(false);

            // Check for expired conversation
            if (ExpireAfter.HasValue && (DateTime.UtcNow - lastAccess) >= TimeSpan.FromMilliseconds((double)ExpireAfter))
            {
                // Clear conversation state
                await ConversationState.ClearStateAsync(context, cancellationToken).ConfigureAwait(false);
            }

            lastAccess = DateTime.UtcNow;
            await lastAccessProperty.SetAsync(context, lastAccess, cancellationToken).ConfigureAwait(false);

            // get dialog stack
            var dialogsProperty = ConversationState.CreateProperty <DialogState>(_dialogStateProperty);
            var dialogState     = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken).ConfigureAwait(false);

            // Create DialogContext
            var dc = new DialogContext(Dialogs, context, dialogState);

            // Call the common dialog "continue/begin" execution pattern shared with the classic RunAsync extension method
            var turnResult = await DialogExtensions.InternalRunAsync(context, _rootDialogId, dc, cancellationToken).ConfigureAwait(false);

            // save BotState changes
            await botStateSet.SaveAllChangesAsync(dc.Context, false, cancellationToken).ConfigureAwait(false);

            return(new DialogManagerResult {
                TurnResult = turnResult
            });
        }
示例#24
0
        /// <summary>
        /// Runs dialog system in the context of an ITurnContext.
        /// </summary>
        /// <param name="context">turn context.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>result of the running the logic against the activity.</returns>
        public async Task <DialogManagerResult> OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default)
        {
            var botStateSet = new BotStateSet();

            // Preload TurnState with DM TurnState.
            foreach (var pair in InitialTurnState)
            {
                context.TurnState.Set(pair.Key, pair.Value);
            }

            // register DialogManager with TurnState.
            context.TurnState.Set(this);

            if (ConversationState == null)
            {
                ConversationState = context.TurnState.Get <ConversationState>() ?? throw new InvalidOperationException($"Unable to get an instance of {nameof(ConversationState)} from turnContext.");
            }
            else
            {
                context.TurnState.Set(ConversationState);
            }

            botStateSet.Add(ConversationState);

            if (UserState == null)
            {
                UserState = context.TurnState.Get <UserState>();
            }
            else
            {
                context.TurnState.Set(UserState);
            }

            if (UserState != null)
            {
                botStateSet.Add(UserState);
            }

            // create property accessors
            var lastAccessProperty = ConversationState.CreateProperty <DateTime>(LastAccess);
            var lastAccess         = await lastAccessProperty.GetAsync(context, () => DateTime.UtcNow, cancellationToken).ConfigureAwait(false);

            // Check for expired conversation
            if (ExpireAfter.HasValue && (DateTime.UtcNow - lastAccess) >= TimeSpan.FromMilliseconds((double)ExpireAfter))
            {
                // Clear conversation state
                await ConversationState.ClearStateAsync(context, cancellationToken).ConfigureAwait(false);
            }

            lastAccess = DateTime.UtcNow;
            await lastAccessProperty.SetAsync(context, lastAccess, cancellationToken).ConfigureAwait(false);

            // get dialog stack
            var dialogsProperty = ConversationState.CreateProperty <DialogState>(_dialogStateProperty);
            var dialogState     = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken).ConfigureAwait(false);

            // Create DialogContext
            var dc = new DialogContext(Dialogs, context, dialogState);

            // promote initial TurnState into dc.services for contextual services
            foreach (var service in dc.Services)
            {
                dc.Services[service.Key] = service.Value;
            }

            // map TurnState into root dialog context.services
            foreach (var service in context.TurnState)
            {
                dc.Services[service.Key] = service.Value;
            }

            // get the DialogStateManager configuration
            var dialogStateManager = new DialogStateManager(dc, StateConfiguration);
            await dialogStateManager.LoadAllScopesAsync(cancellationToken).ConfigureAwait(false);

            dc.Context.TurnState.Add(dialogStateManager);

            DialogTurnResult turnResult = null;

            // Loop as long as we are getting valid OnError handled we should continue executing the actions for the turn.
            //
            // NOTE: We loop around this block because each pass through we either complete the turn and break out of the loop
            // or we have had an exception AND there was an OnError action which captured the error.  We need to continue the
            // turn based on the actions the OnError handler introduced.
            var endOfTurn = false;

            while (!endOfTurn)
            {
                try
                {
                    if (context.TurnState.Get <IIdentity>(BotAdapter.BotIdentityKey) is ClaimsIdentity claimIdentity && SkillValidation.IsSkillClaim(claimIdentity.Claims))
                    {
                        // The bot is running as a skill.
                        turnResult = await HandleSkillOnTurnAsync(dc, cancellationToken).ConfigureAwait(false);
                    }
                    else
                    {
                        // The bot is running as root bot.
                        turnResult = await HandleBotOnTurnAsync(dc, cancellationToken).ConfigureAwait(false);
                    }

                    // turn successfully completed, break the loop
                    endOfTurn = true;
                }
示例#25
0
文件: Startup.cs 项目: onebluecube/AI
        public void ConfigureServices(IServiceCollection services)
        {
            // Load the connected services from .bot file.
            var botFilePath   = Configuration.GetSection("botFilePath")?.Value;
            var botFileSecret = Configuration.GetSection("botFileSecret")?.Value;
            var botConfig     = BotConfiguration.Load(botFilePath ?? @".\CustomAssistant.bot", botFileSecret);

            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded."));

            // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection.
            var skills            = Configuration.GetSection("skills").Get <List <SkillDefinition> >();
            var connectedServices = new BotServices(botConfig, skills);

            services.AddSingleton(sp => connectedServices);

            var defaultLocale = Configuration.GetSection("defaultLocale").Get <string>();

            // Initialize Bot State
            var cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file.");
            var cosmosDb        = cosmosDbService as CosmosDbService;
            var cosmosOptions   = new CosmosDbStorageOptions()
            {
                CosmosDBEndpoint = new Uri(cosmosDb.Endpoint),
                AuthKey          = cosmosDb.Key,
                CollectionId     = cosmosDb.Collection,
                DatabaseId       = cosmosDb.Database,
            };
            var dataStore         = new CosmosDbStorage(cosmosOptions);
            var userState         = new UserState(dataStore);
            var conversationState = new ConversationState(dataStore);

            services.AddSingleton(dataStore);
            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(new BotStateSet(userState, conversationState));

            var environment = _isProduction ? "production" : "development";
            var service     = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment);

            if (!(service is EndpointService endpointService))
            {
                throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
            }

            services.AddSingleton(endpointService);

            // Add the bot with options
            services.AddBot <VirtualAssistant>(options =>
            {
                // Load the connected services from .bot file.
                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Telemetry Middleware (logs activity messages in Application Insights)
                var appInsightsService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.AppInsights) ?? throw new Exception("Please configure your AppInsights connection in your .bot file.");
                var instrumentationKey = (appInsightsService as AppInsightsService).InstrumentationKey;
                var appInsightsLogger  = new TelemetryLoggerMiddleware(instrumentationKey, logUserName: true, logOriginalMessage: true);
                options.Middleware.Add(appInsightsLogger);

                // Catches any errors that occur during a conversation turn and logs them to AppInsights.
                options.OnTurnError = async(context, exception) =>
                {
                    CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale);
                    var responseBuilder          = new MainResponses();
                    await responseBuilder.ReplyWith(context, MainResponses.ResponseIds.Error);
                    await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Virtual Assistant Error: {exception.Message} | {exception.StackTrace}"));
                    connectedServices.TelemetryClient.TrackException(exception);
                };

                // Transcript Middleware (saves conversation history in a standard format)
                var storageService       = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file.");
                var blobStorage          = storageService as BlobStorageService;
                var transcriptStore      = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container);
                var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore);
                options.Middleware.Add(transcriptMiddleware);

                // Typing Middleware (automatically shows typing when the bot is responding/working)
                options.Middleware.Add(new ShowTypingMiddleware());
                options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en-us"));
                options.Middleware.Add(new EventDebuggerMiddleware());
                options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState));

                //// Translator is an optional component for scenarios when an Assistant needs to work beyond native language support
                // var translatorKey = Configuration.GetValue<string>("translatorKey");
                // if (!string.IsNullOrEmpty(translatorKey))
                // {
                //     options.Middleware.Add(new TranslationMiddleware(new string[] { "en", "fr", "it", "de", "es" }, translatorKey, false));
                // }
                // else
                // {
                //     throw new InvalidOperationException("Microsoft Text Translation API key is missing. Please add your translation key to the 'translatorKey' setting.");
                // }
            });
        }
示例#26
0
        public async Task EnsureCancelDialogCalled()
        {
            var convoState = new ConversationState(new MemoryStorage());

            var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                          .Use(new AutoSaveStateMiddleware(convoState));

            var dialogState      = convoState.CreateProperty <DialogState>("dialogState");
            var dialogs          = new DialogSet(dialogState);
            var telemetryClient  = new Mock <IBotTelemetryClient>();
            var saved_properties = new Dictionary <string, IDictionary <string, string> >();
            var counter          = 0;

            // Set up the client to save all logged property names and associated properties (in "saved_properties").
            telemetryClient.Setup(c => c.TrackEvent(It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <IDictionary <string, double> >()))
            .Callback <string, IDictionary <string, string>, IDictionary <string, double> >((name, properties, metrics) => saved_properties.Add($"{name}_{counter++}", properties))
            .Verifiable();

            var steps = new WaterfallStep[]
            {
                async(step, cancellationToken) =>
                {
                    await step.Context.SendActivityAsync("step1");

                    return(Dialog.EndOfTurn);
                },
                async(step, cancellationToken) =>
                {
                    await step.Context.SendActivityAsync("step2");

                    return(Dialog.EndOfTurn);
                },
                async(step, cancellationToken) =>
                {
                    await step.CancelAllDialogsAsync();

                    return(Dialog.EndOfTurn);
                },
            };
            var waterfallDialog = new MyWaterfallDialog("test", steps);

            dialogs.Add(waterfallDialog);
            dialogs.TelemetryClient = telemetryClient.Object;

            await new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken);
                await dc.ContinueDialogAsync(cancellationToken);
                if (!turnContext.Responded)
                {
                    await dc.BeginDialogAsync("test", null, cancellationToken);
                }
            })
            .Send("hello")
            .AssertReply("step1")
            .Send("hello")
            .AssertReply("step2")
            .Send("hello")
            .AssertReply("step1")
            .StartTestAsync();
            telemetryClient.Verify(m => m.TrackEvent(It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <IDictionary <string, double> >()), Times.Exactly(7));

            // Verify:
            // Event name is "WaterfallCancel"
            // Event occurs on the 4th event logged
            // Event contains DialogId
            // Event DialogId is set correctly.
            Assert.IsTrue(saved_properties["WaterfallStart_0"].ContainsKey("DialogId"));
            Assert.IsTrue(saved_properties["WaterfallStart_0"].ContainsKey("InstanceId"));
            Assert.IsTrue(saved_properties["WaterfallCancel_4"].ContainsKey("DialogId"));
            Assert.IsTrue(saved_properties["WaterfallCancel_4"]["DialogId"] == "test");
            Assert.IsTrue(saved_properties["WaterfallCancel_4"].ContainsKey("StepName"));
            Assert.IsTrue(saved_properties["WaterfallCancel_4"].ContainsKey("InstanceId"));

            // Event contains "StepName"
            // Event naming on lambda's is "StepXofY"
            Assert.IsTrue(saved_properties["WaterfallCancel_4"]["StepName"] == "Step3of3");
            Assert.IsTrue(waterfallDialog.CancelDialogCalled);
            Assert.IsFalse(waterfallDialog.EndDialogCalled);
        }
 public TestInspectionMiddleware(InspectionState inspectionState, UserState userState, ConversationState conversationState, HttpClient httpClient)
     : base(inspectionState, userState, conversationState)
 {
     _httpClient = httpClient;
 }
示例#28
0
        public AdapterWithErrorHandler(IConfiguration configuration, ILogger <BotFrameworkHttpAdapter> logger, SentimentMiddleware sentimentMiddleware, ConversationState conversationState = null)
            : base(configuration, logger)
        {
            if (sentimentMiddleware == null)
            {
                throw new NullReferenceException(nameof(sentimentMiddleware));
            }

            // Add translation middleware to the adapter's middleware pipeline
            Use(sentimentMiddleware);

            OnTurnError = async(turnContext, exception) =>
            {
                // Log any leaked exception from the application.
                logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");

                // Send a message to the user
                await turnContext.SendActivityAsync("The bot encounted an error or bug.");

                await turnContext.SendActivityAsync("To continue to run this bot, please fix the bot source code.");

                if (conversationState != null)
                {
                    try
                    {
                        // Delete the conversationState for the current conversation to prevent the
                        // bot from getting stuck in a error-loop caused by being in a bad state.
                        // ConversationState should be thought of as similar to "cookie-state" in a Web pages.
                        await conversationState.DeleteAsync(turnContext);
                    }
                    catch (Exception e)
                    {
                        logger.LogError(e, $"Exception caught on attempting to Delete ConversationState : {e.Message}");
                    }
                }

                // Send a trace activity, which will be displayed in the Bot Framework Emulator
                await SendTraceActivityAsync(turnContext, exception);
            };
        }
        public async Task ScenarioWithInspectionMiddlwareOpenAttach()
        {
            // Arrange

            // any bot state should be returned as trace messages per turn
            var storage           = new MemoryStorage();
            var inspectionState   = new InspectionState(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);

            // set up the middleware with an http client that will just record the traffic - we are expecting the trace activities here
            var recordingHttpClient  = new RecordingHttpMessageHandler();
            var inspectionMiddleware = new TestInspectionMiddleware(
                inspectionState,
                userState,
                conversationState,
                new HttpClient(recordingHttpClient));

            // Act

            // (1) send the /INSPECT open command from the emulator to the middleware
            var openActivity = MessageFactory.Text("/INSPECT open");

            var inspectionAdapter = new TestAdapter(Channels.Test, true);
            await inspectionAdapter.ProcessActivityAsync(openActivity, async (turnContext, cancellationToken) =>
            {
                await inspectionMiddleware.ProcessCommandAsync(turnContext);
            });

            var inspectionOpenResultActivity = inspectionAdapter.ActiveQueue.Dequeue();

            // (2) send the resulting /INSPECT attach command from the channel to the middleware
            var applicationAdapter = new TestAdapter(Channels.Test, true);

            applicationAdapter.Use(inspectionMiddleware);

            var attachCommand = inspectionOpenResultActivity.Value.ToString();

            await applicationAdapter.ProcessActivityAsync(MessageFactory.Text(attachCommand), async (turnContext, cancellationToken) =>
            {
                // nothing happens - just attach the inspector
                await Task.CompletedTask;
            });

            var attachResponse = applicationAdapter.ActiveQueue.Dequeue();

            // (3) send an application messaage from the channel, it should get the reply and then so should the emulator http endpioint
            await applicationAdapter.ProcessActivityAsync(MessageFactory.Text("hi"), async (turnContext, cancellationToken) =>
            {
                await turnContext.SendActivityAsync(MessageFactory.Text($"echo: {turnContext.Activity.Text}"));

                (await userState.CreateProperty <Scratch>("x").GetAsync(turnContext, () => new Scratch())).Property         = "hello";
                (await conversationState.CreateProperty <Scratch>("y").GetAsync(turnContext, () => new Scratch())).Property = "world";
                await userState.SaveChangesAsync(turnContext);
                await conversationState.SaveChangesAsync(turnContext);
            });

            // Assert
            var outboundActivity = applicationAdapter.ActiveQueue.Dequeue();

            Assert.Equal("echo: hi", outboundActivity.Text);
            Assert.Equal(3, recordingHttpClient.Requests.Count);

            var inboundTrace = JObject.Parse(recordingHttpClient.Requests[0]);

            Assert.Equal("trace", inboundTrace["type"].ToString());
            Assert.Equal("ReceivedActivity", inboundTrace["name"].ToString());
            Assert.Equal("message", inboundTrace["value"]["type"].ToString());
            Assert.Equal("hi", inboundTrace["value"]["text"].ToString());

            var outboundTrace = JObject.Parse(recordingHttpClient.Requests[1]);

            Assert.Equal("trace", outboundTrace["type"].ToString());
            Assert.Equal("SentActivity", outboundTrace["name"].ToString());
            Assert.Equal("message", outboundTrace["value"]["type"].ToString());
            Assert.Equal("echo: hi", outboundTrace["value"]["text"].ToString());

            var stateTrace = JObject.Parse(recordingHttpClient.Requests[2]);

            Assert.Equal("trace", stateTrace["type"].ToString());
            Assert.Equal("BotState", stateTrace["name"].ToString());
            Assert.Equal("hello", stateTrace["value"]["userState"]["x"]["Property"].ToString());
            Assert.Equal("world", stateTrace["value"]["conversationState"]["y"]["Property"].ToString());
        }
示例#30
0
        public BotFrameworkHttpAdapter GetBotAdapter(IStorage storage, BotSettings settings, UserState userState, ConversationState conversationState, IServiceProvider s)
        {
            var adapter = IsSkill(settings)
                ? new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration), s.GetService<AuthenticationConfiguration>())
                : new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration));

            adapter
              .UseStorage(storage)
              .UseBotState(userState, conversationState)
              .Use(new RegisterClassMiddleware<IConfiguration>(Configuration))
              .Use(s.GetService<TelemetryInitializerMiddleware>());

            // Configure Middlewares
            ConfigureTranscriptLoggerMiddleware(adapter, settings);
            ConfigureInspectionMiddleWare(adapter, settings, storage);
            ConfigureShowTypingMiddleWare(adapter, settings);
            ConfigureSetSpeakMiddleWare(adapter, settings);

            adapter.OnTurnError = async (turnContext, exception) =>
            {
                await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);
                await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);
                await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
            };
            return adapter;
        }
示例#31
0
        public void ConfigureServices(IServiceCollection services)
        {
            var environment = _isProduction ? "production" : "development";

            // Load the connected services from .bot file.
            var botFilePath = Configuration.GetSection("botFilePath")?.Value;
            //var botFileSecret = Configuration.GetSection("botFileSecret")?.Value;
            var botFileSecret = "dTonuuzS+krI6S69RITRAII7T/hAqtLYM1BLN7/eqAI=";

            var botConfig = BotConfiguration.Load(botFilePath, botFileSecret);

            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded."));

            // Get default locale from appsettings.json
            var defaultLocale = Configuration.GetSection("defaultLocale").Get <string>();

            // Use Application Insights
            services.AddBotApplicationInsights(botConfig);

            // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection.
            var connectedServices = new BotServices(botConfig);

            services.AddSingleton(sp => connectedServices);

            // Initialize Bot State
            var cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file.");
            var cosmosDb        = cosmosDbService as CosmosDbService;
            var cosmosOptions   = new CosmosDbStorageOptions()
            {
                CosmosDBEndpoint = new Uri(cosmosDb.Endpoint),
                AuthKey          = cosmosDb.Key,
                CollectionId     = cosmosDb.Collection,
                DatabaseId       = cosmosDb.Database,
            };
            var dataStore         = new CosmosDbStorage(cosmosOptions);
            var userState         = new UserState(dataStore);
            var conversationState = new ConversationState(dataStore);
            var jobState          = new JobState(dataStore);

            services.AddSingleton(sp => jobState);
            services.AddSingleton(dataStore);
            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(new BotStateSet(userState, conversationState));

            // Add the bot with options
            services.AddBot <Bot>(options =>
            {
                var service = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment);
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }

                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Telemetry Middleware (logs activity messages in Application Insights)
                var sp = services.BuildServiceProvider();
                var telemetryClient = sp.GetService <IBotTelemetryClient>();

                var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true);
                options.Middleware.Add(appInsightsLogger);

                // Catches any errors that occur during a conversation turn and logs them to AppInsights.
                options.OnTurnError = async(context, exception) =>
                {
                    telemetryClient.TrackException(exception);
                    await context.SendActivityAsync(MainStrings.ERROR);
                };

                // Transcript Middleware (saves conversation history in a standard format)
                var storageService       = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file.");
                var blobStorage          = storageService as BlobStorageService;
                var transcriptStore      = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container);
                var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore);
                options.Middleware.Add(transcriptMiddleware);

                // Typing Middleware (automatically shows typing when the bot is responding/working)
                options.Middleware.Add(new ShowTypingMiddleware());

                // Locale Middleware (sets UI culture based on Activity.Locale)
                options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en-us"));

                // Autosave State Middleware (saves bot state after each turn)
                options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState));
            });

            services.AddSingleton(sp =>
            {
                var service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment);
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }

                return((EndpointService)service);
            });
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RewardAndRecognitionAdapterWithErrorHandler"/> class.
        /// </summary>
        /// <param name="configuration">Application configurations.</param>
        /// <param name="logger">Instance to send logs to the Application Insights service.</param>
        /// <param name="rewardAndRecognitionActivityMiddleWare">Represents middle ware that can operate on incoming activities.</param>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="conversationState">conversationState.</param>
        public RewardAndRecognitionAdapterWithErrorHandler(IConfiguration configuration, ILogger <IBotFrameworkHttpAdapter> logger, RewardAndRecognitionActivityMiddleware rewardAndRecognitionActivityMiddleWare, IStringLocalizer <Strings> localizer, ConversationState conversationState = null)
            : base(configuration)
        {
            if (rewardAndRecognitionActivityMiddleWare == null)
            {
                throw new NullReferenceException(nameof(rewardAndRecognitionActivityMiddleWare));
            }

            // Add activity middle ware to the adapter's middle ware pipeline
            this.Use(rewardAndRecognitionActivityMiddleWare);

            this.OnTurnError = async(turnContext, exception) =>
            {
                // Log any leaked exception from the application.
                logger.LogError(exception, $"Exception caught : {exception.Message}");

                // Send a catch-all apology to the user.
                await turnContext.SendActivityAsync(localizer.GetString("ErrorMessage"));

                if (conversationState != null)
                {
                    try
                    {
                        // Delete the conversationState for the current conversation to prevent the
                        // bot from getting stuck in a error-loop caused by being in a bad state.
                        // ConversationState should be thought of as similar to "cookie-state" in a Web pages.
                        await conversationState.DeleteAsync(turnContext);
                    }
                    #pragma warning disable CA1031 // Do not catch general exception types
                    catch (Exception ex)
                    #pragma warning restore CA1031 // Do not catch general exception types
                    {
                        logger.LogError(ex, $"Exception caught on attempting to Delete ConversationState : {ex.Message}");
                    }
                }
            };
        }
 protected void GoToNode(int index)
 {
     currentNode = index;
     lastDialogueTick = Time.time;
     _state = ConversationState.DIALOGUE_PAUSE;
 }
示例#34
0
        public GetReminderController(IBotFrameworkHttpAdapter adapter, IConfiguration configuration, ConversationState conversationState,
                                     ILogger <MainDialog> logger,
                                     ConcurrentDictionary <string, ConversationReference> conversationReferences,
                                     ICredentialProvider credentialProvider, IBot bot)
        {
            this.bot = bot as DialogBot <MainDialog>;
            _adapter = adapter;
            _conversationReferences = conversationReferences;
            ConversationState       = conversationState;
            _appId       = configuration["MicrosoftAppId"];
            _appPassword = configuration["MicrosoftAppPassword"];
            _botId       = configuration["BotId"];
            _botName     = configuration["BotName"];

            _logger             = logger;
            _configuration      = configuration;
            _credentialProvider = credentialProvider;

            // If the channel is the Emulator, and authentication is not in use,
            // the AppId will be null.  We generate a random AppId for this case only.
            // This is not required for production, since the AppId will have a value.
            if (string.IsNullOrEmpty(_appId))
            {
                _appId = Guid.NewGuid().ToString(); //if no AppId, use a random Guid
            }
        }
示例#35
0
    void HandleKeyPress()
    {
        if (Input.GetKeyUp(KeyCode.E))
        {
            if (!InteractingWith)
            {
                //interactie met iets
                NPC closest = null;
                float c = float.MaxValue;

                bool looping = true;
                while (looping)
                {
                    foreach (NPC npc in (NPC[])GameObject.FindObjectsOfType<NPC>())
                    {
                        bool nothit = true;
                        float dist = Vector3.Distance(this.transform.position, npc.gameObject.transform.position);
                        if (dist < c)
                        {
                            closest = npc;
                            c = dist;

                            nothit = true;
                        }

                        if (nothit)
                            looping = false;
                    }
                }
                if (c < 3.5f) //interact range!!!
                {
                    if (closest.Interact())
                    {                        
                        //zoom in camera
                        InteractingWith = true;
                        InteractingNPC = closest;
                    }
                }
            }
            else
            { 
                //volgende regel?
                if (ConvState == ConversationState.NPC)
                    ConvState = ConversationState.Player;
                else
                    ConvState = ConversationState.NPC;

                InteractingNPC.NextConversationLine();
            }
        }

        SetItemMoving(false);

        if (Input.GetKey(KeyCode.W))
        {
            SetItemMoving(true);
            TargetPosition += new Vector3(0, 0, 1.0f / MoveSpeed);
            SetItemFacing(ItemFacing.Up);

            if (Facing != FacingDirection.Front)
            {
                GetComponent<Renderer>().material.mainTexture = textures[0];
                Facing = FacingDirection.Front;                
            }
        }
        if (Input.GetKey(KeyCode.S))
        {
            SetItemMoving(true);            
            TargetPosition += new Vector3(0, 0, -1.0f / MoveSpeed);
            SetItemFacing(ItemFacing.Down);

            if (Facing != FacingDirection.Back)
            {
                //change sprite
                GetComponent<Renderer>().material.mainTexture = textures[1];
                Facing = FacingDirection.Back;
            }
        }
        if (Input.GetKey(KeyCode.A))
        {
            SetItemMoving(true);
            TargetPosition += new Vector3(-1.0f / MoveSpeed, 0, 0);
            SetItemFacing(ItemFacing.Left);

            if (Facing != FacingDirection.Left)
            {
                GetComponent<Renderer>().material.mainTexture = textures[2];
                Facing = FacingDirection.Left;
            }
        }
        if (Input.GetKey(KeyCode.D))
        {
            SetItemMoving(true);
            TargetPosition += new Vector3(1.0f / MoveSpeed, 0, 0);
            SetItemFacing(ItemFacing.Right);

            if (Facing != FacingDirection.Right)
            {
                GetComponent<Renderer>().material.mainTexture = textures[3];
                Facing = FacingDirection.Right;
            }
        }                      
    }
        public async Task ChoicePrompt()
        {
            var dialogs = new DialogSet();

            dialogs.Add("test-prompt", new Dialogs.ChoicePrompt(Culture.English)
            {
                Style = ListStyle.Inline
            });

            var promptOptions = new ChoicePromptOptions
            {
                Choices = new List <Choice>
                {
                    new Choice {
                        Value = "red"
                    },
                    new Choice {
                        Value = "green"
                    },
                    new Choice {
                        Value = "blue"
                    },
                },
                RetryPromptString = "I didn't catch that. Select a color from the list."
            };

            dialogs.Add("test",
                        new WaterfallStep[]
            {
                async(dc, args, next) =>
                {
                    await dc.PromptAsync("test-prompt", "favorite color?", promptOptions);
                },
                async(dc, args, next) =>
                {
                    var choiceResult = (ChoiceResult)args;
                    await dc.Context.SendActivityAsync($"Bot received the choice '{choiceResult.Value.Value}'.");
                    await dc.EndAsync();
                }
            }
                        );

            var activities = TranscriptUtilities.GetFromTestContext(TestContext);

            var convState    = new ConversationState(new MemoryStorage());
            var testProperty = convState.CreateProperty <Dictionary <string, object> >("test", () => new Dictionary <string, object>());

            TestAdapter adapter = new TestAdapter()
                                  .Use(convState);

            await new TestFlow(adapter, async(turnContext) =>
            {
                if (turnContext.Activity.Type == ActivityTypes.Message)
                {
                    var state = await testProperty.GetAsync(turnContext);
                    var dc    = dialogs.CreateContext(turnContext, state);

                    await dc.ContinueAsync();

                    if (!turnContext.Responded)
                    {
                        await dc.BeginAsync("test");
                    }
                }
            })
            .Test(activities)
            .StartTestAsync();
        }
 public void ResetCurrent()
 {
     CheckState(ConversationState.InContext);
     CurrentConversationHolder.Instance.UnBind(_map);
     foreach(ISession session in _map.Values)
     {
         session.Transaction.Commit();
     }
     _state = ConversationState.Opened;
 }
    // Update is called once per frame
    protected virtual void Update()
    {
        if (!_conversationIsRunning)
            return;

        switch(_state) {
        case ConversationState.DIALOGUE_PAUSE:
            Debug.Log ("DialoguePause");
            // Pause between two conversation nodes
            if (!endTimerHasBeenSet) {
                endTimer = Time.time;
                endTimerHasBeenSet = true;
            }

            if (HasRenderedCompleteDialogueLine &&
                (Time.time - endTimer) > CurrentNode.NextNodeDelay) {
                _state = ConversationState.RENDERING_DIALOGUE;
                textBubble.gameObject.SetActive(true);
                henryBubble.gameObject.SetActive(false);
                endTimerHasBeenSet = false;
                lastDialogueTick = Time.time;
            }
            break;
        case ConversationState.RENDERING_DIALOGUE:
            Debug.Log ("RenderingDialogue");
            if (HasRenderedCompleteDialogueLine ||
                Input.GetKeyDown(KeyCode.Return))     // ...The player wants to skip the JRPG thang?
            {
                _state = ConversationState.ANSWERING_APPERANCE_DELAY;
                lastDialogueTick = -1000; // minus a lot, because if lastTick = 0 the time difference may not be big enough to cause the entire string to be rendered.
            }
            break;
        case ConversationState.ANSWERING_APPERANCE_DELAY:
            Debug.Log ("AnsweringDelay");
            // Wait before showing the responses and start listening for player input
            if (!endTimerHasBeenSet) {
                endTimer = Time.time;
                endTimerHasBeenSet = true;
            }

            if (HasRenderedCompleteDialogueLine &&
                (Time.time - endTimer) > CurrentNode.AnswerAppearanceDelay) {
                _state = ConversationState.SELECTION_TIME;
                endTimerHasBeenSet = false;
            }
            break;
        case ConversationState.SELECTION_TIME:
            Debug.Log ("SelectionTime");
            // Controls
            // This state will wait for player input
            if ( (Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.W)) &&
                _highlightedResponse != 0) {
                _highlightedResponse--;
            }
            if ( (Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.S)) &&
                _highlightedResponse != CurrentNode.Responses.Length-1) {
                _highlightedResponse++;
            }
            if (Input.GetKeyDown (KeyCode.Return) && !CurrentNode.IsEndNode) {
                // When player selects a response, transition to the AWKWARD state, where the response will eventually be chosen after awkward silence
                _state = ConversationState.AWKWARD;
                henryBubble.gameObject.SetActive(true);
                lastDialogueTick = Time.time;
                if (CurrentNode.IsEndNode)
                    endTimer = Time.time;
            }

            // Check whether conversation should skip ahead if no answer is selected
            if (CurrentNode.SilentResponse > 0.0) {
                if (!nodeTimerHasBeenSet) {
                    nodeTimer = Time.time;
                    nodeTimerHasBeenSet = true;
                }

                if (Time.time - nodeTimer > CurrentNode.SilentResponse) {
                    nodeTimerHasBeenSet = false;
                    GoToNode(CurrentNode.SilentGoto);
                }
            }

            int endConvoNodeDisplayTime = 3;
            if (CurrentNode.IsEndNode && CurrentNode.SilentResponse <= 0.0 &&
                (Time.time - endTimer) > endConvoNodeDisplayTime)
                StopConversation();

            break;
        case ConversationState.AWKWARD:
            // The AWKWARD state will wait awkwardly after the player selects a response before actually selecting the response and moving to next node
            // When the waiting time is 0, the response will be selected instantly. That is why SELECTION_TIME doesn't select responses directly.
            Debug.Log("Awkward");
            if (
                Time.time - endTimer > CurrentNode.AnsweringDelay) {
                textBubble.gameObject.SetActive(false);

                endTimer = Time.time;
                _state = ConversationState.DIALOGUE_PAUSE;
                lastDialogueTick = Time.time;
                SelectResponse(_highlightedResponse);
            }
            break;

        }
    }
        public AdapterWithErrorHandler(IConfiguration configuration, IHttpClientFactory httpClientFactory, ILogger<IBotFrameworkHttpAdapter> logger, ConversationState conversationState = default)
            : base(configuration, httpClientFactory, logger)
        {
            OnTurnError = async (turnContext, exception) =>
            {
                // Log any leaked exception from the application.
                // NOTE: In production environment, you should consider logging this to
                // Azure Application Insights. Visit https://aka.ms/bottelemetry to see how
                // to add telemetry capture to your bot.
                logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");

                // Send a message to the user
                await turnContext.SendActivityAsync("The bot encountered an error or bug.");
                await turnContext.SendActivityAsync("To continue to run this bot, please fix the bot source code.");

                // Send a trace activity, which will be displayed in the Bot Framework Emulator
                await SendTraceActivityAsync(turnContext, exception);
            };
        }
示例#40
0
	// Update is called once per frame
	void Update () {        
        HandleKeyPress();
        Animate();

        if (!InteractingWith)
        {
            if (transform.position != TargetPosition)
            {
                bool valid = true;
                Vector3 newpos = Vector3.Lerp(this.transform.position, TargetPosition, Time.deltaTime * 10);
                foreach (NPC npc in (NPC[])GameObject.FindObjectsOfType<NPC>())
                {
                    float dist = Vector3.Distance(newpos, npc.gameObject.transform.position);
                    if (dist < 3.0f)
                    {
                        valid = false;
                        break;
                    }
                }

                if (valid)
                    this.transform.position = newpos;
            }
        }
        else
        {
            string n = InteractingNPC.GetConversationLine();
            if (n != "END")
                DisplayText(n);
            else
            {
                ConvState = ConversationState.NPC;

                InteractingWith = false;
                InteractingNPC.SetConversationLine(true);
                
                PlayerConvText.GetComponent<TextMesh>().text = "";
            }
        }
                       
        ((Weapon)activeItem).UpdatePosition(this.transform);
	}
        public AdaptiveBotAdapter(ICredentialProvider credentialProvider, IConfiguration configuration, ILogger <BotFrameworkHttpAdapter> logger, IStorage storage, UserState userState, ConversationState conversationState, ResourceExplorer resourceExplorer)
        {
            this.Use(new RegisterClassMiddleware <IConfiguration>(configuration));
            this.UseStorage(storage);
            this.UseState(userState, conversationState);
            this.UseResourceExplorer(resourceExplorer);
            this.UseLanguageGeneration(resourceExplorer);
            this.UseAdaptiveDialogs();

            this.OnTurnError = async(turnContext, exception) =>
            {
                if (conversationState != null)
                {
                    // clear the conversationState to ensure that the next request for user will be routed to a new conversation
                    await conversationState.DeleteAsync(turnContext);
                }
            };
        }
示例#42
0
 public AlexaHeroBot(T dialog, ILogger <HeroBot <T> > logger, ConversationState conversationState)
 {
     _dialog            = dialog;
     _logger            = logger;
     _conversationState = conversationState;
 }
 public IDisposable SetAsCurrent()
 {
     CheckState(ConversationState.Opened);
     foreach(ISession session in _map.Values)
     {
         session.BeginTransaction();
     }
     CurrentConversationHolder.Instance.Bind(_map);
     _state = ConversationState.InContext;
     return new DisposeAction(ResetCurrent);
 }