0
votes

In Luis, I created a simple pattern with a simple entity like this:

list bots {Name}

where "Name" is my entity that I would like to get in C#. The pattern and intent works fine and I am getting that correctly.

I follow the official example and built a IRecognizerConvert class so I can deserialize the result. It deserialize the intent just fine but fail to deserialize the entity.

In the _Entities sub-class, I only have the "Name" variable that I am trying to deserialize and nothing else. I don't have any other partial class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Newtonsoft.Json;
using Microsoft.Bot.Builder.AI.Luis;

namespace EmptyBot1.Models
{
    public class ChatbotIntent : IRecognizerConvert
    {
        public string Text;
        public string AlteredText;
        public enum Intent
        {
            CreateBot,
            ListBots,
            ListAllBots,
            RunBot,
            Cancel,
            Greet,
            None
        };
        public Dictionary<Intent, IntentScore> Intents;

        public class _Entities
        {
            public string Name;
        }
        public _Entities Entities;

        [JsonExtensionData(ReadData = true, WriteData = true)]
        public IDictionary<string, object> Properties { get; set; }

        public void Convert(dynamic result)
        {
            var _result = JsonConvert.DeserializeObject<ChatbotIntent>(JsonConvert.SerializeObject(result, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }));
            Text = _result.Text;
            AlteredText = _result.AlteredText;
            Intents = _result.Intents;
            Entities = _result.Entities;
            Properties = _result.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);
        }
    }
}

In the previous snippet, the important part is the _Entities class which define how the entities look from coming back from Luis. Since I only have 1 simple string entity "Name", I thought this is sufficient.

        public class _Entities
        {
            public string Name;
        }

However when I run it and I give it an utterance like:

"list bots mybots"

Luis would correctly assign Name="mybots" and get the correct intent, but it crash on the JsonConvert.DeserializeObject line saying the json format is incorrect. I assume this is complaining about the class I made? And not the actual JSON result from luis?

What do I need to add to the _Entities class so the luis entity can be successfully deserialzied?

2
Have you tried using LUISGen instead of creating the class by yourself? It's a command tool from the Microsoft team for exactly this - generating the IRecognizerConvert instance. At the very least, it might help you see what parts it generates differently.Hilton Giesenow
I haven't, I will definitely try it! Thank you for pointing that out to me.Bill Software Engineer
Glad to help, let me know if you run into any trouble with itHilton Giesenow
As Hilton specified above, you can make use of LUISGen comand line tool for generating strongle typed class for the intents and entities defined in the LUIS model. Also , you can have a look at this SO issue which is similar to yours.ranusharao
Yup worked out great! Thanks guys!Bill Software Engineer

2 Answers

3
votes

I know this is an old question but I'm facing the same situation now so I want to contribute with the step-by-step that worked for me. As @ranusharao and Bill said, you need to download LUISGen from GitHub. Start a CMD, go to your solution's directory

cd C:\MySolutionFolder

and run

luis init

if you haven't done yet. It will ask you for your App ID and information that you get in luis.ai. After that, go to luis.ai / Manage / Versions, click on your current version and click Export as Json. enter image description here Place your JSON file in your solution's folder. Once you have done that, run the following command in your console:

LUISGen C:\MyJSONPath\MyBot.json -cs MyClassName -o C:\MySolutionFolder

That -cs stands for C#, but if you are usign Typescript then change it for "-ts". So there you have it, you can access your class with something like:

var result = await _luisRecognizerService._recognizer.RecognizeAsync<MyClassName>(turnContext, cancellationToken);
Console.WriteLine(result.Entities.Producto);

_luisRecognizerService is my instance of LuisRecognizer (dependency injection)

0
votes

As recommended by @ranusharao, using LUISGen tool, a class will automatically be generated that works with the bot framework.