using System.Collections.Generic; using System; using AI.Models.Form; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; namespace AI.Utils { /// /// 将表单定义序列化为 YAML,供 LLM 上下文、追踪、调试等使用。 /// public static class FormSchemaYamlGenerator { /// /// System 消息中「表单 Schema YAML」块的开始标记(存在则整块替换,避免重复追加)。 /// public const string FormsYamlBlockStart = "\n\n# --- 当前可用表单 Schema (YAML) ---\n"; /// /// System 消息中「表单 Schema YAML」块的结束标记。 /// public const string FormsYamlBlockEnd = "\n# --- 结束 ---"; /// /// 将现有 System 内容与新的表单 YAML 合并:若已包含标记块则替换该块,否则在末尾追加。 /// public static string MergeFormsYamlIntoSystemContent(string currentSystemContent, string formsYaml) { var block = FormsYamlBlockStart + formsYaml + FormsYamlBlockEnd; if (string.IsNullOrEmpty(currentSystemContent)) return block.TrimStart('\n'); if (currentSystemContent.Contains(FormsYamlBlockStart)) { int start = currentSystemContent.IndexOf(FormsYamlBlockStart, StringComparison.Ordinal); int end = currentSystemContent.IndexOf(FormsYamlBlockEnd, start, StringComparison.Ordinal); if (end >= 0) { end += FormsYamlBlockEnd.Length; } else { end = currentSystemContent.Length; } return currentSystemContent.Remove(start, end - start).Insert(start, block); } return currentSystemContent + block; } /// /// 将当前可用表单定义生成为 YAML 字符串。 /// public static string ToYaml(IEnumerable forms) { var schema = new FormsSchemaYaml { Forms = BuildForms(forms) }; var serializer = new SerializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull | DefaultValuesHandling.OmitDefaults) .Build(); // 保留顶部说明注释(内容不参与结构序列化)。 return "# 当前可用表单 Schema(供助手了解可展示的表单与字段)\n" + serializer.Serialize(schema); } private static List BuildForms(IEnumerable? forms) { var list = new List(); foreach (var form in forms ?? []) { var formYaml = new FormYaml { Id = form.Id, Title = form.Title, SubmitTarget = form.SubmitTarget, SubmitLabel = form.SubmitLabel, Fields = BuildFields(form.Fields) }; list.Add(formYaml); } return list; } private static List BuildFields(IReadOnlyList? fields) { var list = new List(); foreach (var f in fields ?? []) { list.Add(new FieldYaml { Id = f.Id, Label = f.Label, Description = string.IsNullOrEmpty(f.Description) ? null : f.Description, Type = f.Type.ToString(), Required = f.Required ? true : null, Default = f.DefaultValue == null ? null : f.DefaultValue.ToString(), Min = f.Min, Max = f.Max, Step = f.Step, MaxLength = f.MaxLength, Placeholder = string.IsNullOrEmpty(f.Placeholder) ? null : f.Placeholder, Options = (f.Options != null && f.Options.Count > 0) ? new List(f.Options) : null, DefaultValues = (f.DefaultValues != null && f.DefaultValues.Count > 0) ? new List(f.DefaultValues) : null }); } return list; } private sealed class FormsSchemaYaml { public List Forms { get; init; } = []; } private sealed class FormYaml { public string? Id { get; init; } public string? Title { get; init; } public string? SubmitTarget { get; init; } public string? SubmitLabel { get; init; } public List Fields { get; init; } = []; } private sealed class FieldYaml { public string? Id { get; init; } public string? Label { get; init; } public string? Description { get; init; } public string? Type { get; init; } // 仅在 true 时输出 public bool? Required { get; init; } [YamlMember(Alias = "default")] public string? Default { get; init; } public double? Min { get; init; } public double? Max { get; init; } public double? Step { get; init; } public int? MaxLength { get; init; } public string? Placeholder { get; init; } public List? Options { get; init; } public List? DefaultValues { get; init; } } } }