Files
codex 7777b349a5
PR and Push Build/Test / build-and-test (push) Successful in 6m37s
Archive summary refinements and profile switching
2026-05-27 23:11:21 +02:00

120 lines
3.6 KiB
C#

using DiffPlex.DiffBuilder;
using DiffPlex.DiffBuilder.Model;
using MeetingAssistant.MeetingNotes;
using System.Text;
namespace MeetingAssistant.Summary;
public sealed class SummaryAgentWriteAudit
{
private readonly MeetingSessionArtifacts artifacts;
private readonly List<FileChange> changes = [];
public SummaryAgentWriteAudit(MeetingSessionArtifacts artifacts)
{
this.artifacts = artifacts;
}
public async Task CaptureFileWriteAsync(
string path,
Func<Task> writeOperation,
CancellationToken cancellationToken = default)
{
var fullPath = Path.GetFullPath(path);
var before = File.Exists(fullPath)
? await File.ReadAllTextAsync(fullPath, cancellationToken)
: "";
await writeOperation();
var after = File.Exists(fullPath)
? await File.ReadAllTextAsync(fullPath, cancellationToken)
: "";
Capture(fullPath, before, after, cancellationToken);
}
public void Capture(
string path,
string before,
string after,
CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
var fullPath = Path.GetFullPath(path);
if (IsOwnedArtifact(fullPath) || string.Equals(before, after, StringComparison.Ordinal))
{
return;
}
var diffLines = CreateDiffLines(before, after);
if (diffLines.Count == 0)
{
return;
}
changes.Add(new FileChange(fullPath, diffLines));
}
public async Task AppendToAssistantContextAsync(CancellationToken cancellationToken)
{
if (changes.Count == 0)
{
return;
}
if (!File.Exists(artifacts.AssistantContextPath))
{
return;
}
var existing = await File.ReadAllTextAsync(artifacts.AssistantContextPath, cancellationToken);
var builder = new StringBuilder();
if (!string.IsNullOrEmpty(existing) && !existing.EndsWith(Environment.NewLine, StringComparison.Ordinal))
{
builder.AppendLine();
}
builder.AppendLine();
builder.AppendLine("## Summary Agent External File Changes");
builder.AppendLine();
foreach (var change in changes)
{
builder.AppendLine($"### {change.Path}");
builder.AppendLine();
builder.AppendLine("```diff");
foreach (var line in change.DiffLines)
{
builder.AppendLine(line);
}
builder.AppendLine("```");
builder.AppendLine();
}
await File.AppendAllTextAsync(artifacts.AssistantContextPath, builder.ToString(), cancellationToken);
}
private bool IsOwnedArtifact(string fullPath)
{
return IsSamePath(fullPath, artifacts.SummaryPath) ||
IsSamePath(fullPath, artifacts.AssistantContextPath);
}
private static bool IsSamePath(string first, string second)
{
return string.Equals(
Path.GetFullPath(first),
Path.GetFullPath(second),
StringComparison.OrdinalIgnoreCase);
}
private static List<string> CreateDiffLines(string before, string after)
{
var model = InlineDiffBuilder.Diff(before, after);
return model.Lines
.Where(line => line.Type is ChangeType.Deleted or ChangeType.Inserted)
.Select(line => $"{(line.Type == ChangeType.Inserted ? "+" : "-")} {line.Text}")
.ToList();
}
private sealed record FileChange(string Path, IReadOnlyList<string> DiffLines);
}