Exemple #1
0
        private bool InitializeSkill(DialogContext dc)
        {
            if (dc.ActiveDialog.State.ContainsKey(ActiveSkillStateKey))
            {
                var skill = dc.ActiveDialog.State[ActiveSkillStateKey] as SkillService;

                var cosmosDbOptions = _cosmosDbOptions;
                cosmosDbOptions.CollectionId = skill.Name;
                var cosmosDbStorage   = new CosmosDbStorage(cosmosDbOptions);
                var conversationState = new ConversationState(cosmosDbStorage);

                try
                {
                    var skillType = Type.GetType(skill.Assembly);
                    _activatedSkill = (IBot)Activator.CreateInstance(skillType, conversationState, $"{skill.Name}State", skill.Configuration);
                }
                catch (Exception e)
                {
                    var message = $"Skill ({skill.Name}) Type could not be created.";
                    throw new InvalidOperationException(message, e);
                }

                _inProcAdapter = new InProcAdapter
                {
                    OnTurnError = async(context, exception) =>
                    {
                        await dc.Context.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : exception.Message));

                        await context.SendActivityAsync(context.Activity.CreateReply($"Sorry, something went wrong trying to communicate with the skill. Please try again."));

                        await dc.Context.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : $"Skill Error: {exception.Message} | {exception.StackTrace}"));

                        _telemetryClient.TrackException(exception);
                    },
                };

                _inProcAdapter.Use(new EventDebuggerMiddleware());
                _inProcAdapter.Use(new AutoSaveStateMiddleware(conversationState));

                skillInitialized = true;
            }
            else
            {
                // No active skill?
            }

            return(skillInitialized);
        }
Exemple #2
0
        private async Task InitializeSkill(DialogContext dc)
        {
            try
            {
                var skillDefinition    = dc.ActiveDialog.State[ActiveSkillStateKey] as SkillDefinition;
                var skillConfiguration = _skills[skillDefinition.Id];

                IStorage storage;

                if (skillConfiguration.CosmosDbOptions != null)
                {
                    var cosmosDbOptions = skillConfiguration.CosmosDbOptions;
                    cosmosDbOptions.CollectionId = skillDefinition.Name;
                    storage = new CosmosDbStorage(cosmosDbOptions);
                }
                else
                {
                    storage = new MemoryStorage();
                }

                // Initialize skill state
                var userState         = new UserState(storage);
                var conversationState = new ConversationState(storage);

                // Create skill instance
                try
                {
                    var skillType = Type.GetType(skillDefinition.Assembly);
                    _activatedSkill = (IBot)Activator.CreateInstance(skillType, skillConfiguration, conversationState, userState, _telemetryClient, null, true);
                }
                catch (Exception e)
                {
                    var message = $"Skill ({skillDefinition.Name}) could not be created.";
                    throw new InvalidOperationException(message, e);
                }

                _inProcAdapter = new InProcAdapter
                {
                    // set up skill turn error handling
                    OnTurnError = async(context, exception) =>
                    {
                        await context.SendActivityAsync(context.Activity.CreateReply(CommonResponses.ErrorMessage_SkillError));

                        await dc.Context.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : $"Skill Error: {exception.Message} | {exception.StackTrace}"));

                        // Log exception in AppInsights
                        skillConfiguration.TelemetryClient.TrackException(exception);
                    },
                };

                _inProcAdapter.Use(new EventDebuggerMiddleware());
                _inProcAdapter.Use(new SetLocaleMiddleware(dc.Context.Activity.Locale ?? "en-us"));
                _inProcAdapter.Use(new AutoSaveStateMiddleware(userState, conversationState));
                _skillInitialized = true;
            }
            catch
            {
                // something went wrong initializing the skill, so end dialog cleanly and throw so the error is logged
                _skillInitialized = false;
                await dc.EndDialogAsync();

                throw;
            }
        }
Exemple #3
0
        private bool InititializeSkill(DialogContext dc)
        {
            if (dc.ActiveDialog.State.ContainsKey(ActiveSkillStateKey))
            {
                var skill = dc.ActiveDialog.State[ActiveSkillStateKey] as SkillRegistration;

                var cosmosDbOptions = _cosmosDbOptions;

                // Isolate from the main Bot's storage and put skill state into it's own collection
                cosmosDbOptions.CollectionId = skill.Name;

                // The Skill state will be stored in our parent Bot storage
                var cosmosDbStorage   = new CosmosDbStorage(cosmosDbOptions);
                var conversationState = new ConversationState(cosmosDbStorage);

                // Reflection is used to enable dynamic lookup of Skills and keep it configuration based
                // A configuration driven approach is elegant but Reflection is pretty heavyweight, explore DI
                try
                {
                    // Create the skill and crucially pass the provided Conversation State in through a new constructor specific to skill activation
                    var skillType = Type.GetType(skill.Assembly);
                    activatedSkill = (IBot)Activator.CreateInstance(skillType, conversationState, $"{skill.Name}State", skill.Configuration);
                }
                catch (Exception e)
                {
                    var message = $"Skill ({skill.Name}) Type could not be created.";

                    throw new InvalidOperationException(message, e);
                }

                // Initialise the Adapter and Middlware used to invoke Skills. We leverage the same Storage account as configured by the parent Bot otherwise the Parent Bot would need
                // To know about all of the storage information for each skill and cause an explosion of Skill state stores. This approach keeps things simple and ensures Skill state is owned/managed
                // By the parent Bot which feels the right way forward.
                // We create our own "collection" for Skills state.
                inProcAdapter = new InProcAdapter
                {
                    OnTurnError = async(context, exception) =>
                    {
                        await dc.Context.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : exception.Message));

                        await context.SendActivityAsync(context.Activity.CreateReply($"Sorry, something went wrong trying to communicate with the skill. Please try again."));

                        await dc.Context.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : $"Skill Error: {exception.Message} | {exception.StackTrace}"));

                        _telemetryClient.TrackException(exception);
                    },
                };

                inProcAdapter.Use(new EventDebuggerMiddleware());

                // TODO: Send property bag across to skill from registration
                inProcAdapter.Use(new AutoSaveStateMiddleware(conversationState));

                skillInitialized = true;
            }
            else
            {
                // No active skill?
            }

            return(skillInitialized);
        }
Exemple #4
0
        private async Task InitializeSkill(DialogContext dc)
        {
            try
            {
                IStorage storage;

                if (_skillConfiguration.CosmosDbOptions != null)
                {
                    var cosmosDbOptions = _skillConfiguration.CosmosDbOptions;
                    cosmosDbOptions.CollectionId = _skillDefinition.Name;
                    storage = new CosmosDbStorage(cosmosDbOptions);
                }
                else
                {
                    storage = new MemoryStorage();
                }

                // Initialize skill state
                var userState         = new UserState(storage);
                var conversationState = new ConversationState(storage);

                // Create skill instance
                try
                {
                    var skillType = Type.GetType(_skillDefinition.Assembly);

                    // Have to use refined BindingFlags to allow for optional parameters on constructors.
                    _activatedSkill = (IBot)Activator.CreateInstance(
                        skillType,
                        BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance | BindingFlags.OptionalParamBinding,
                        default(Binder),
                        new object[] { _skillConfiguration, _endpointService, conversationState, userState, _proactiveState, _telemetryClient, _backgroundTaskQueue, true },
                        CultureInfo.CurrentCulture);
                }
                catch (Exception e)
                {
                    var message = $"Skill ({_skillDefinition.Name}) could not be created.";
                    throw new InvalidOperationException(message, e);
                }

                _inProcAdapter = new InProcAdapter
                {
                    // set up skill turn error handling
                    OnTurnError = async(context, exception) =>
                    {
                        await context.SendActivityAsync(_responseManager.GetResponse(CommonResponses.ErrorMessage_SkillError));

                        await dc.Context.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : $"Skill Error: {exception.Message} | {exception.StackTrace}"));

                        // Log exception in AppInsights
                        _telemetryClient.TrackExceptionEx(exception, context.Activity);
                    },
                    BackgroundTaskQueue = _backgroundTaskQueue
                };

                _inProcAdapter.Use(new EventDebuggerMiddleware());
                _inProcAdapter.Use(new SetLocaleMiddleware(dc.Context.Activity.Locale ?? "en-us"));
                _inProcAdapter.Use(new AutoSaveStateMiddleware(userState, conversationState));
                _skillInitialized = true;
            }
            catch
            {
                // something went wrong initializing the skill, so end dialog cleanly and throw so the error is logged
                _skillInitialized = false;
                await dc.EndDialogAsync();

                throw;
            }
        }