I have a virtual assistant dispatch that hands off control to a knowledge base skill that makes use of QnA maker. I will eventually have several QnA knowledgebases, but right now, I'm running into an issue getting the first one working. I've created/edited, trained, and publised/released the QnA maker KB, Knowledge Base Skill Luis model, and the Virtual Assistant's dispatch model.
Exception is being generated after the successful skill dispatch when my Knowledge Base Skill's Luis model returns the intent. I have a switch statement that will eventually point to the knowledge base corresponding to the user's question.
text: "Exception Message: Could not convert string 'helpdesk_faq' to dictionary key type
'Luis.KnowledgeBaseSkillLuis+Intent'. Create a TypeConverter to convert
from the string to the key type object.
I updated my KnowledgeBaseSkillLuis.cs
intent enumeration with the name of the new intent (shown below), but I'm wondering if I didn't need to do this. I noticed my KnowledgeBaseSkill.luis
and Faq.qna
files do not have the updated changes; which leads me to my question -
How do I pull the updated models into my local environment? Do I need to run a botskills or dispatch command to pull the newly published intents into the code, or was I correct in manually updating the intent enumeration with my new skill? Do I need to re-publish the Assistant and/or Skill from my local machine to Azure to get them?
I've read these articles, but I'm struggling to make use of them:
// Full file included lower in the post
public enum Intent
{
Sample,
q_Faq,
helpdesk_faq, // Newly created intent (others were auto generated with Deploy scripts provided in skill template
None
};
MainDialog.cs
:
...
switch (intent)
{
case KnowledgeBaseSkillLuis.Intent.Sample:
{
await innerDc.BeginDialogAsync(_sampleDialog.Id);
break;
}
case KnowledgeBaseSkillLuis.Intent.helpdesk_faq:
{
cognitiveModels.QnAServices.TryGetValue("Faq", out var qnaService); // "Faq" is the name of the QnA maker knowledge base.
if (qnaService == null)
{
await innerDc.Context.SendActivityAsync("I'm having issues looking up the information for you.");
throw new Exception("QnA Maker Service could not be found in the Bot Services Configuration.");
}
else
{
var answers = await qnaService.GetAnswersAsync(innerDc.Context, null, null);
if (answers != null && answers.Count() > 0)
{
await innerDc.Context.SendActivityAsync(answers[0].Answer);
}
else
{
await innerDc.Context.SendActivityAsync(_templateEngine.GenerateActivityForLocale("ConfusedMessage"));
}
}
break;
}
case KnowledgeBaseSkillLuis.Intent.None:
default:
{
// intent was identified but not yet implemented
await innerDc.Context.SendActivityAsync(_templateEngine.GenerateActivityForLocale("UnsupportedMessage"));
break;
}
}
...
KnowledgeBaseSkillLuis.cs
:
public class KnowledgeBaseSkillLuis : IRecognizerConvert
{
public string Text;
public string AlteredText;
public enum Intent
{
Sample,
q_Faq,
helpdesk_faq,
None
};
public Dictionary<Intent, IntentScore> Intents;
public class _Entities
{
// Instance
public class _Instance
{
}
[JsonProperty("$instance")]
public _Instance _instance;
}
public _Entities Entities;
[JsonExtensionData(ReadData = true, WriteData = true)]
public IDictionary<string, object> Properties { get; set; }
public void Convert(dynamic result)
{
var app = JsonConvert.DeserializeObject<KnowledgeBaseSkillLuis>(JsonConvert.SerializeObject(result));
Text = app.Text;
AlteredText = app.AlteredText;
Intents = app.Intents;
Entities = app.Entities;
Properties = app.Properties;
}
public (Intent intent, double score) TopIntent()
{
Intent maxIntent = Intent.None;
var max = 0.0;
foreach (var entry in Intents)
{
if (entry.Value.Score > max)
{
maxIntent = entry.Key;
max = entry.Value.Score.Value;
}
}
return (maxIntent, max);
}
}