I am working on creating a workflow which allows composer created dialogs to be integrated into a bot skill project.
To accomplish this I am trying to follow the instructions in this post: https://microsoft.github.io/botframework-solutions/skills/handbook/experimental-add-composer/
My composer created dialogs including calling a skill. When I initiate that intent through the Bot Emulator I get this error:
System.NullReferenceException: 'Unable to locate SkillConversationIdFactoryBase in HostContext'
The setup to get to this error is time consuming so I have created a git repo which can be started fairly easily to demonstrate the issue.
The project can be found here: https://github.com/silverbulletgt/Integrate-Composer-Dialog-Using-Skill
To recreate the issue:
Prerequisites
Step to Recreate the Issue
Open the solution file in visual studio
Integrate-Composer-Dialog-Using-Skill.sln
Put a breakpoint on line 72
of DefaultAdapter.cs
- this is where the error can be seen
Start debugging the project
Open Bot Emulator
Connect to the bot: http://localhost:3978/api/messages
Type "Greeting"
Bot should respond with "Hello, I have recognized that you said greeting"
- This means that the composer dialog integration is working as expected.
Type "Skill"
The breakpoint on line 72
of DefaultAdapter.cs
should trigger giving details of the error.
Error & stack trace can be found here: https://github.com/silverbulletgt/Integrate-Composer-Dialog-Using-Skill/blob/master/Readme/error%20stack%20trace.txt
Edit:
I was able to compile the Bot Builder code Bot Builder GitHub & connect it to my project so that I could debug. I found the error to be happening on line 157
of Microsoft.Bot.Builder.Dialogs.Adaptive.BeginSkill.cs
code BeginSkill.cs.
This line is trying to get the SkillConversationFactoryBase
out of the dialogContext.Context.TurnState
. I'm investigating how I might add this so that it is populated when this code executes.
This error was being caused by missing dependency injection requirements. Added the below lines to Startup.cs
services.AddSingleton<SkillConversationIdFactoryBase, SkillConversationIdFactory>();
services.AddSingleton<HttpClient>(new HttpClient());
services.AddSingleton<BotFrameworkClient, BotFrameworkHttpClient>();
Added to DefaultAdapter.cs
New Field
private readonly SkillConversationIdFactoryBase _skillConversationIdFactoryBase;
New constructor parameters
SkillConversationIdFactoryBase skillConversationIdFactoryBase,
BotFrameworkClient botFrameworkClient
To the body of the constructor
_skillConversationIdFactoryBase = skillConversationIdFactoryBase;
Use(new RegisterClassMiddleware<SkillConversationIdFactoryBase>(_skillConversationIdFactoryBase));
Use(new RegisterClassMiddleware<BotFrameworkClient>(botFrameworkClient));
This fixed the initial exception however there was then a new exception when the skill was called.
Exception wasOperation returned an invalid status code 'NotFound' at Microsoft.Bot.Connector.Conversations.d__10.MoveNext()
I added SkillController.cs based on the example here: Bot Builder Tests JSON SkillController
Then added dependency injection to support the controller. Added to Startup.cs
services.AddSingleton<ChannelServiceHandler, SkillHandler>();
services.AddSingleton<BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService<IBotFrameworkHttpAdapter>());
I tested a basic intent which does not use a skill to determine if there would be any conflict with the dependency injection impacting those. The basic intent worked as expected though.
I updated the master branch with the changes Project Repo