0

我正在使用 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是否必须显示。这可行,但在那之后机器人会出现“抱歉,我的机器人代码有问题

文本错误的示例 文本错误的示例

带有正确文本的示例 带有正确文本的示例

编辑

表单中使用的类:

类 BaseModel

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

类城

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; }
}
4

1 回答 1

1

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

路易斯对话

[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 中的字段之前对其进行处理,则必须在 Luis Dialog 方法本身中进行。

于 2018-06-21T11:03:04.390 回答