using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SemanticKernel.ChatCompletion;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace AI.Models.Store
{
///
/// 会话存储序列化用的 DTO(YAML 根为 entries 列表)
///
public class ConversationStoreDto
{
public List Entries { get; set; } = new();
}
///
/// 单条存储条目的 DTO
///
public class ConversationEntryDto
{
public string Kind { get; set; } = string.Empty;
public string? Role { get; set; }
public string? Content { get; set; }
public string? Type { get; set; }
public string? Payload { get; set; }
}
///
/// 会话级结构化存储,作为 UI 与 Prompt 构建的唯一事实来源。
/// 持有有序的 ConversationEntry 列表,支持追加文本与特殊消息。
/// 每个 ChatSession 持有一份 ConversationStore 实例。
///
public class ConversationStore
{
private readonly List _entries = new();
private static readonly ISerializer _yamlSerializer = new SerializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
private static readonly IDeserializer _yamlDeserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.IgnoreUnmatchedProperties()
.Build();
///
/// 有序条目列表(只读视图)
///
public IReadOnlyList Entries => _entries;
///
/// 存储内容变更时触发(用于持久化层按需保存)
///
public event EventHandler? StoreChanged;
///
/// 追加一条文本消息
///
public void AppendText(AuthorRole role, string content)
{
_entries.Add(new TextConversationEntry(role, content ?? string.Empty));
StoreChanged?.Invoke(this, EventArgs.Empty);
}
///
/// 追加一条特殊消息(type + YAML 载荷)
///
public void AppendSpecial(string type, string yamlPayload)
{
_entries.Add(new SpecialConversationEntry(type ?? string.Empty, yamlPayload ?? string.Empty));
StoreChanged?.Invoke(this, EventArgs.Empty);
}
///
/// 清空存储(用于测试或重置)
///
public void Clear()
{
_entries.Clear();
}
///
/// 移除最后一条条目(用于回滚等)
///
/// 是否移除了条目
public bool RemoveLast()
{
if (_entries.Count == 0) return false;
_entries.RemoveAt(_entries.Count - 1);
return true;
}
///
/// 条目数量
///
public int Count => _entries.Count;
///
/// 序列化为 YAML 字符串(仅 entries 列表,用于嵌入会话文件或单独观察)
///
public string ToYaml()
{
var dto = new ConversationStoreDto
{
Entries = ConversationEntryMapper.ToDtoList(_entries)
};
return _yamlSerializer.Serialize(dto);
}
///
/// 从 YAML 字符串加载并替换当前存储内容(先清空再按序追加)
///
public void LoadFromYaml(string yaml)
{
if (string.IsNullOrWhiteSpace(yaml))
{
Clear();
return;
}
var dto = _yamlDeserializer.Deserialize(yaml);
LoadFromEntries(dto?.Entries);
}
///
/// 从 DTO 条目列表加载并替换当前存储(先清空再按序追加),用于会话文件反序列化
///
public void LoadFromEntries(IEnumerable? entries)
{
_entries.Clear();
_entries.AddRange(ConversationEntryMapper.ToEntryList(entries));
}
}
}