Archive summary refinements and profile switching
PR and Push Build/Test / build-and-test (push) Successful in 6m37s

This commit is contained in:
2026-05-27 23:11:21 +02:00
parent c12febe029
commit 7777b349a5
37 changed files with 3190 additions and 121 deletions
@@ -1,5 +1,6 @@
using MeetingAssistant.MeetingNotes;
using Microsoft.Extensions.Options;
using YamlDotNet.Serialization;
namespace MeetingAssistant.Summary;
@@ -12,14 +13,15 @@ public interface IMeetingSummaryArtifactResolver
Task<MeetingSessionArtifacts?> ResolveBySummaryPathAsync(
string summaryPath,
MeetingAssistantOptions options,
CancellationToken cancellationToken)
{
return ResolveBySummaryPathAsync(summaryPath, cancellationToken);
}
CancellationToken cancellationToken);
}
public sealed class MeetingSummaryArtifactResolver : IMeetingSummaryArtifactResolver
{
private static readonly IDeserializer YamlDeserializer = new DeserializerBuilder()
.IgnoreUnmatchedProperties()
.Build();
private readonly MeetingAssistantOptions options;
private readonly IMeetingNoteStore meetingNoteStore;
@@ -49,6 +51,14 @@ public sealed class MeetingSummaryArtifactResolver : IMeetingSummaryArtifactReso
return null;
}
var summaryArtifacts = await ResolveFromSummaryFrontmatterAsync(
requestedSummaryPath,
cancellationToken);
if (summaryArtifacts is not null)
{
return summaryArtifacts;
}
var meetingNotesFolder = VaultPath.Resolve(options.Vault, options.Vault.MeetingNotesFolder);
if (!Directory.Exists(meetingNotesFolder))
{
@@ -64,16 +74,77 @@ public sealed class MeetingSummaryArtifactResolver : IMeetingSummaryArtifactReso
continue;
}
return new MeetingSessionArtifacts(
return TryCreateArtifactsFromLinks(
note.Path,
ResolveNoteLink(note.Frontmatter.Transcript, note.Path),
ResolveNoteLink(note.Frontmatter.AssistantContext, note.Path),
requestedSummaryPath);
requestedSummaryPath,
note.Frontmatter.Transcript,
note.Frontmatter.AssistantContext);
}
return null;
}
private static async Task<MeetingSessionArtifacts?> ResolveFromSummaryFrontmatterAsync(
string requestedSummaryPath,
CancellationToken cancellationToken)
{
if (!File.Exists(requestedSummaryPath))
{
return null;
}
var content = await File.ReadAllTextAsync(requestedSummaryPath, cancellationToken);
var (frontmatter, _) = MeetingArtifactFrontmatterRenderer.Split(content);
if (string.IsNullOrWhiteSpace(frontmatter))
{
return null;
}
SummaryArtifactLinks? links;
try
{
links = YamlDeserializer.Deserialize<SummaryArtifactLinks>(frontmatter);
}
catch (YamlDotNet.Core.YamlException)
{
return null;
}
if (string.IsNullOrWhiteSpace(links?.Meeting) ||
string.IsNullOrWhiteSpace(links.Transcript) ||
string.IsNullOrWhiteSpace(links.AssistantContext))
{
return null;
}
return TryCreateArtifactsFromLinks(
requestedSummaryPath,
requestedSummaryPath,
links.Transcript,
links.AssistantContext,
links.Meeting);
}
private static MeetingSessionArtifacts? TryCreateArtifactsFromLinks(
string sourceNotePath,
string requestedSummaryPath,
string transcriptLink,
string assistantContextLink,
string? meetingLink = null)
{
var assistantContextPath = ResolveNoteLink(assistantContextLink, sourceNotePath);
if (string.IsNullOrWhiteSpace(assistantContextPath) || !File.Exists(assistantContextPath))
{
return null;
}
return new MeetingSessionArtifacts(
meetingLink is null ? sourceNotePath : ResolveNoteLink(meetingLink, sourceNotePath),
ResolveNoteLink(transcriptLink, sourceNotePath),
assistantContextPath,
requestedSummaryPath);
}
private static string? ResolveRequestedSummaryPath(
string summaryPath,
MeetingAssistantOptions options)
@@ -141,4 +212,16 @@ public sealed class MeetingSummaryArtifactResolver : IMeetingSummaryArtifactReso
var normalizedPath = Path.GetFullPath(path);
return normalizedPath.StartsWith(normalizedDirectory, StringComparison.OrdinalIgnoreCase);
}
private sealed class SummaryArtifactLinks
{
[YamlMember(Alias = "meeting")]
public string? Meeting { get; set; }
[YamlMember(Alias = "transcript")]
public string? Transcript { get; set; }
[YamlMember(Alias = "assistant_context")]
public string? AssistantContext { get; set; }
}
}