gpt4 book ai didi

c# - 如何防止在 FormFlow 中重新验证时显示原始提示?

转载 作者:太空宇宙 更新时间:2023-11-03 12:11:49 24 4
gpt4 key购买 nike

BuildForm Method

        public static IForm<FAQConversation> BuildForm()
{
return new FormBuilder<FAQConversation>()
.Field(new FieldReflector<FAQConversation>(nameof(Inquiry))
.SetValidate(AnswerInquiry)
.SetPrompt(new PromptAttribute("Okay, tell me what is your question. Enter \"back\" to go back to Products Selection."))
)
.Build();
}

Validation Method

        private static async Task<ValidateResult> AnswerInquiry(FAQConversation state, object value)
{
var result = new ValidateResult();
//somecode here
if(testCase == false)
{
result.isValid = false;
result.Feedback = "Try again";
}
else
{
result.isValid = true;
}
return result;
}

当我的验证字段中的输入无效时,我的验证方法返回反馈文本“再试一次”。但是,它同时返回原始提示和反馈文本。

问题
如何删除字段重新验证时的原始提示?

最佳答案

虽然 FormFlow 确实提供了很多可定制性,但其背后的主要思想是为您自动化一切,这往往表明至少有一些东西是非常强大的。

我知道您想做的是在“重试”时禁用字段提示,也就是说,如果用户已经看到字段提示并且他们输入了无效的内容,那么他​​们不应该再次显示提示。我可以在 source code 中看到FormFlow 并没有真正为“重试”提供特殊情况,并且当字段仍然未知时提示的行为是这些内置的东西之一。但是,您仍然可以做一些事情。

FormFlow 提供了一种(大部分未记录的)方法来替换所谓的“提示器”。您可以使用 Prompter() 执行此操作方法,它需要一个 PromptAsyncDelegate .作为新提示器的起点,您可以在 FormBuilder 源代码中找到默认提示器:

_form._prompter = async (context, prompt, state, field) =>
{
var preamble = context.MakeMessage();
var promptMessage = context.MakeMessage();
if (prompt.GenerateMessages(preamble, promptMessage))
{
await context.PostAsync(preamble);
}
await context.PostAsync(promptMessage);
return prompt;
};

虽然默认提示器总是发布 promptMessage,但您的替换可以用 if 语句包围该行。这就留下了你的条件应该是什么的问题。我们已经确定 FormFlow 不包含任何重试概念,因此您必须以某种方式自行构建它。您可以在 FAQConversation 的状态中包含一个 bool 字段作为开关,或者您甚至可以使用 PrivateConversationData,因为提示器允许您访问 DialogContext。您可能认为,当提示显示一次或当 AnswerInquiryAsync 确定用户输入无效时关闭开关是一件简单的事情,但是什么时候开关会重新打开?如果用户输入“back”,你又想再次显示提示怎么办?

虽然您可能会找到一些方法来更准确地表示“重试时禁用提示”的逻辑,但我想出的最简单的解决方案是跟踪 FormFlow 生成的最后一条消息,然后跳过随后出现的第一条消息“再试一次。”它看起来像这样:

[Serializable]
public class FAQConversation
{
public string Inquiry { get; set; }

private string LastMessage { get; set; }

private const string TRY_AGAIN = "Try again";

public static IForm<FAQConversation> BuildForm()
{
return new FormBuilder<FAQConversation>()
// This is an alternative way of using the Field() method but it works the same.
.Field(nameof(Inquiry),
"Okay, tell me what is your question. Enter \"back\" to go back to Products Selection.",
validate: AnswerInquiryAsync)
.Prompter(PromptAsync)
.Build();
}

private static async Task<ValidateResult> AnswerInquiryAsync(FAQConversation state, object value)
{
var result = new ValidateResult();
bool testCase = Equals(value, "true"); // Enter "true" to continue for testing purposes.

if (testCase == false)
{
result.IsValid = false;
// A constant should be used with strings that appear more than once in your code.
result.Feedback = TRY_AGAIN;
}
else
{
result.IsValid = true;
// A value must be provided or else the Field will not be populated.
result.Value = value;
}

return result;
}

/// <summary>
/// Here is the method we're using for the PromptAsyncDelegate.
/// </summary>
private static async Task<FormPrompt> PromptAsync(IDialogContext context, FormPrompt prompt,
FAQConversation state, IField<FAQConversation> field)
{
var preamble = context.MakeMessage();
var promptMessage = context.MakeMessage();

if (prompt.GenerateMessages(preamble, promptMessage))
{
await context.PostAsync(preamble);
}

// Here is where we've made a change to the default prompter.
if (state.LastMessage != TRY_AGAIN)
{
await context.PostAsync(promptMessage);
}

state.LastMessage = promptMessage.Text;

return prompt;
}
}

关于c# - 如何防止在 FormFlow 中重新验证时显示原始提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51839199/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com