using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using AI.Interface;
using AI.Models;
using AI.Models.Form;
using AI.Models.SpecialMessages;
using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace AI.Utils
{
public static class SpecialMessageTypes
{
public const string Form = "Form";
public const string ParameterSet = "ParameterSet";
public const string Table = "Table";
public const string ColumnMatch = "ColumnMatch";
public const string WorkflowStatus = "WorkflowStatus";
public const string KnowledgeBase = "KnowledgeBase";
public const string XyzLoadCard = "XyzLoadCard";
public const string GriddingParamCard = "GriddingParamCard";
}
///
/// 根据 type + YAML 载荷还原 ISpecialMessage。Form 需 IFormRegistry 根据 formId 取 FormDefinition。
/// formId 缺失或 Definition 不存在时降级为占位或只读文本。
///
public static class SpecialMessageDeserializer
{
public static ISpecialMessage? Deserialize(string type, string yamlPayload, IFormRegistry? formRegistry = null)
{
if (string.IsNullOrWhiteSpace(type) || string.IsNullOrWhiteSpace(yamlPayload))
{
return null;
}
try
{
return type.Trim() switch
{
SpecialMessageTypes.Form => DeserializeForm(yamlPayload, formRegistry),
SpecialMessageTypes.ParameterSet => DeserializeParameterSet(yamlPayload),
SpecialMessageTypes.Table => DeserializeTable(yamlPayload),
SpecialMessageTypes.ColumnMatch => DeserializeColumnMatch(yamlPayload),
SpecialMessageTypes.WorkflowStatus => DeserializeWorkflowStatus(yamlPayload),
SpecialMessageTypes.KnowledgeBase => DeserializeKnowledgeBase(yamlPayload),
SpecialMessageTypes.XyzLoadCard => DeserializeXyzLoadCard(yamlPayload),
SpecialMessageTypes.GriddingParamCard => DeserializeGriddingParamCard(yamlPayload),
_ => null
};
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"[SpecialMessageDeserializer] 反序列化失败: type={type}, error={ex}");
return null;
}
}
private static readonly IReadOnlyDictionary ShortDescriptionTable =
new Dictionary(StringComparer.OrdinalIgnoreCase)
{
[SpecialMessageTypes.Form] = ("表单", new[] { "title", "formId" }),
[SpecialMessageTypes.ParameterSet] = ("参数集", new[] { "title" }),
[SpecialMessageTypes.Table] = ("表格", new[] { "title" }),
[SpecialMessageTypes.ColumnMatch] = ("列匹配", new[] { "title" }),
[SpecialMessageTypes.WorkflowStatus] = ("工作流状态", new[] { "title" }),
[SpecialMessageTypes.XyzLoadCard] = ("散点文件加载卡片", new[] { "filePath" }),
[SpecialMessageTypes.GriddingParamCard] = ("网格化参数卡片", Array.Empty()),
};
///
/// 从特殊消息的 type + YAML 载荷生成发给 LLM 的短描述(如「[已展示:表单「加载散点」]」),便于模型理解上下文。
/// 对于 KnowledgeBase 类型,返回完整 rawContent,以便后续轮次 LLM 能看到查到的知识。
///
public static string GetShortDescriptionForLlm(string type, string payload)
{
if (string.IsNullOrWhiteSpace(type))
{
return "[已展示:未知]";
}
if (string.IsNullOrWhiteSpace(payload))
{
return $"[已展示:{type}]";
}
try
{
var dict = FromYaml(payload);
if (dict == null)
{
return $"[已展示:{type}]";
}
// 知识库条目:把完整内容带给 LLM,作为后续对话的参考
if (string.Equals(type.Trim(), SpecialMessageTypes.KnowledgeBase, StringComparison.OrdinalIgnoreCase))
{
var rawContent = GetString(dict, "rawContent");
return string.IsNullOrWhiteSpace(rawContent)
? "[已查询知识库,无匹配内容]"
: $"[来自知识库的参考]{System.Environment.NewLine}{rawContent}";
}
string typeName = type;
string? detail = null;
if (ShortDescriptionTable.TryGetValue(type.Trim(), out var row))
{
typeName = row.TypeName;
foreach (var key in row.DetailKeys)
{
var value = GetString(dict, key);
if (!string.IsNullOrWhiteSpace(value))
{
detail = value;
break;
}
}
}
if (!string.IsNullOrWhiteSpace(detail))
{
return $"[已展示:{typeName}「{detail}」]";
}
return $"[已展示:{typeName}]";
}
catch
{
return $"[已展示:{type}]";
}
}
private static ISpecialMessage? DeserializeForm(string yaml, IFormRegistry? formRegistry)
{
var dict = FromYaml(yaml);
if (dict == null)
{
return null;
}
string formId = GetString(dict, "formId") ?? string.Empty;
FormDefinition? definition = null;
if (formRegistry != null && !string.IsNullOrEmpty(formId))
{
definition = formRegistry.GetForm(formId);
}
if (definition == null)
{
return null; // 降级:无 FormRegistry 或 formId 不存在时不还原表单卡片
}
var formMsg = new FormRequestMessage(definition);
if (TryGet(dict, "id", out var idObj))
{
formMsg.Id = idObj?.ToString() ?? formMsg.Id;
}
if (TryGet(dict, "submitLabel", out var submitObj))
{
formMsg.SubmitLabel = submitObj?.ToString() ?? formMsg.SubmitLabel;
}
if (TryGet(dict, "fields", out var fieldsObj) && fieldsObj is IEnumerable