using System.Text.RegularExpressions; namespace AIStudio.Assistants.BeyondFactsLab; /// /// Fills the placeholders of a prompt of the BeyondFacts Lab, written as {{NAME}} in upper case. /// /// /// A prompt with a placeholder nobody fills is an error, not a prompt with a gap: the model would read the /// placeholder as text. The values are inserted in one pass, so a value which contains a placeholder itself, such /// as a detail the person entered, stays as it is. /// public static partial class BflPromptTemplate { /// /// The language the model answers in. /// public const string RESPONSE_LANGUAGE = "RESPONSE_LANGUAGE"; /// /// How the model addresses the person. /// public const string ADDRESS_FORM = "ADDRESS_FORM"; /// /// The guide of the lab. /// public const string KNOWLEDGE = "KNOWLEDGE"; /// /// The prompt of the step the chat belongs to. /// public const string STEP = "STEP"; /// /// The material the person added to the preparation. /// public const string MATERIALS = "MATERIALS"; /// /// What the person entered into the forms. /// public const string DETAILS = "DETAILS"; /// /// The key details the forms still lack. /// public const string MISSING_DETAILS = "MISSING_DETAILS"; /// /// The work states the person confirmed. /// public const string WORK_STATES = "WORK_STATES"; /// /// The sections of the work state the model writes. /// public const string SECTIONS = "SECTIONS"; /// /// The empty fields of the form for which the model may suggest values. /// public const string FIELDS = "FIELDS"; /// /// Fills every placeholder of a template. /// /// The template. /// The value of each placeholder, by its name. /// The prompt. /// The template has a placeholder without a value. public static string Fill(string template, IReadOnlyDictionary values) => PlaceholderPattern().Replace(template, match => { var name = match.Groups["name"].Value; return values.TryGetValue(name, out var value) ? value : throw new FormatException($"The prompt has the placeholder '{name}', which has no value."); }); /// /// Finds the placeholders of a template, as Fill reads them. /// /// The template. /// The name of each placeholder, once each, in the order they first appear. public static IReadOnlyList NamesIn(string template) => [.. PlaceholderPattern().Matches(template).Select(match => match.Groups["name"].Value).Distinct(StringComparer.Ordinal)]; [GeneratedRegex(@"\{\{\s*(?[^{}]*?)\s*\}\}")] private static partial Regex PlaceholderPattern(); }