将带有Luis的实体传递给FormFlow

时间:2018-06-21 09:19:04

标签: c# .net botframework luis formflow

我正在使用Luis识别用户是否从某些实体开始流程,例如:他可以说“ 报告”或“ 我想在伦敦报告 >”或“ 我想报告伦敦的x地点

    [LuisIntent("Report")]
    public async Task ReportCompleteIntent(IDialogContext context, LuisResult result)
    {
        EntityRecommendation location;
        EntityRecommendation POS;

        result.TryFindEntity("Weather.Location", out location);
        result.TryFindEntity("POS", out POS);

        //I tried with passing entities (it doesn't recognize the entities in formBuild)
        context.Call(Chain.From(() => new FormDialog<OutOfStockReport>(new OutOfStockReport(), buildForm: OutOfStockReport.BuildForm, options: FormOptions.PromptInStart, entities: result.Entities)), OOSDialogComplete);
        //Also tried prepopulating the state
        context.Call(Chain.From(() => new FormDialog<OutOfStockReport>(new OutOfStockReport() { LocalizationId = location?.Entity }, buildForm: OutOfStockReport.BuildForm, options: FormOptions.PromptInStart)), OOSDialogComplete);
    }

这是类和构建形式:

[Serializable]
[Template(TemplateUsage.NavigationFormat, "{&}")]
public class OutOfStockReport
{
    public string LocalizationId;
    public string PositionId;     

    public static IForm<OutOfStockReport> BuildForm()
    {
        return FormBuilderHelper.CreateCustomForm<OutOfStockReport>()
            .Message("Welcome!")         
            .Field(new FieldReflector<OutOfStockReport>(nameof(LocalizationId))
                .SetType(null)
                .SetActive(hasLocation)
                .SetDefine(async (state, field) =>
                {
                    var cities = new City().GetCities();

                    foreach (var option in cities)
                    {
                        var description = new DescribeAttribute($"{option.Name}", message: $"{option.Name}", title: $"{option.Name}");
                        field.AddDescription(option.Id, description);
                        field.AddTerms(option.Id, Language.GenerateTerms(Language.CamelCase(option.Name), 3));
                    }

                    return true;
                })
                .SetValidate(async (state, response) =>
                {
                    state.PositionId = null;

                    var result = new ValidateResult { IsValid = true, Value = response };

                    return result;

                }))
            .Field(new FieldReflector<OutOfStockReport>(nameof(PositionId))
                .SetType(null)
                .SetActive((state) => !string.IsNullOrEmpty(state.LocalizationId))
                .SetDefine(async (state, field) =>
                {
                    field.RemoveValues();

                    var localizedOptions = new Position().GetPositions(state.LocalizationId);

                    foreach (var option in localizedOptions)
                    {
                        var description = new DescribeAttribute($"{option.Name}", message: $"{option.Name}", title: $"{option.Name}");
                        field.AddDescription(option.Id, description);
                        field.AddTerms(option.Id, Language.GenerateTerms(Language.CamelCase($"{option.Id} {option.Name} {option.Direction}"), 3));
                    }

                    return true;
                }))
            .AddRemainingFields()       
            .Confirm("Are you sure of your selection?{||}")
            .OnCompletion(async (context, state) => await context.PostAsync($"Thanks, the task is complete."))                    
            .Build();

如果添加 ActiveDelegate hasLocation ,我可以控制是否必须显示字段 LocationId 。这可以正常工作,但是之后该机器人以“ 抱歉,我的机器人代码出现问题

带有错误文本的示例 example with wrong text

带有正确文字的示例 example with right text

编辑

以以下形式使用的类:

Class BaseModel

public class BaseModel
{
    public string Id{ get; set; }
}

Class City

public class City : BaseModel
{
    public string Name { get; set; }
}

班级职位

public class Position : BaseModel
{
    public string Name { get; set; }
    public string Direction { get; set; }
    public string CityId { get; set; }
}

1 个答案:

答案 0 :(得分:1)

一种简单的方法是解析Luis结果并从结果中获取实体值,并将结果传递给formflow。

LuisDialog

[LuisIntent("Report")]
public async Task ReportCompleteIntent(IDialogContext context, LuisResult result)
{
        OutOfStockReport form = new OutOfStockReport();
        EntityRecommendation location;
        EntityRecommendation POS;

        if(result.TryFindEntity("Weather.Location", out location))
        {
        //Here you are initializing the form with values.
        //If you have written any validation code for this field then
        //formflow will check the validation when the form is called

             form.Location = location.Entity;
        }
        if(result.TryFindEntity("POS", out POS))
        {
             form.POS = POS.Entity;
        }

        context.Call(form,OutOfStockReport.BuildForm, FormOptions.PromptInStart,OOSDialogComplete);

}

如果必须在将实体分配给Formflow中的字段之前处理该实体,则必须在“路易斯对话框”方法本身中进行处理。