Public Access
Copy meeting projects to summary frontmatter
This commit is contained in:
@@ -56,6 +56,8 @@ public sealed class MeetingSummaryToolTests
|
||||
Assert.Contains("end_time: \"2026-05-20T10:30:00.0000000+02:00\"", summary);
|
||||
Assert.Contains("attendees:", summary);
|
||||
Assert.Contains("- Ada", summary);
|
||||
Assert.Contains("projects:", summary);
|
||||
Assert.Contains("- Meeting Assistant", summary);
|
||||
Assert.Contains("meeting: \"[[../Notes/meeting|Meeting Note]]\"", summary);
|
||||
Assert.Contains("transcript: \"[[../Transcripts/transcript|Transcript]]\"", summary);
|
||||
Assert.Contains("assistant_context: \"[[../Assistant Context/context|Assistant Context]]\"", summary);
|
||||
@@ -106,6 +108,49 @@ public sealed class MeetingSummaryToolTests
|
||||
Assert.DoesNotContain("- Grace", summary);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteSummaryCopiesCurrentMeetingProjectsOverExistingSummaryProjects()
|
||||
{
|
||||
var root = Path.Combine(Path.GetTempPath(), "meeting-assistant-tests", Guid.NewGuid().ToString("N"));
|
||||
var artifacts = new MeetingSessionArtifacts(
|
||||
MeetingNotePath: Path.Combine(root, "Meetings", "Notes", "meeting.md"),
|
||||
TranscriptPath: Path.Combine(root, "Meetings", "Transcripts", "transcript.md"),
|
||||
AssistantContextPath: Path.Combine(root, "Meetings", "Assistant Context", "context.md"),
|
||||
SummaryPath: Path.Combine(root, "Meetings", "Summaries", "summary.md"));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(artifacts.MeetingNotePath)!);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(artifacts.SummaryPath)!);
|
||||
await File.WriteAllTextAsync(
|
||||
artifacts.MeetingNotePath,
|
||||
"""
|
||||
---
|
||||
title: Meeting
|
||||
projects:
|
||||
- Current Project
|
||||
- Second Project
|
||||
---
|
||||
""");
|
||||
await File.WriteAllTextAsync(
|
||||
artifacts.SummaryPath,
|
||||
"""
|
||||
---
|
||||
title: Existing
|
||||
projects:
|
||||
- Stale Project
|
||||
---
|
||||
|
||||
Old summary.
|
||||
""");
|
||||
var tools = new MeetingSummaryTools(artifacts);
|
||||
|
||||
await tools.WriteSummary("# Summary");
|
||||
|
||||
var summary = await File.ReadAllTextAsync(artifacts.SummaryPath);
|
||||
Assert.Contains("projects:", summary);
|
||||
Assert.Contains("- Current Project", summary);
|
||||
Assert.Contains("- Second Project", summary);
|
||||
Assert.DoesNotContain("- Stale Project", summary);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadToolsSupportClampedLineRanges()
|
||||
{
|
||||
|
||||
@@ -12,6 +12,8 @@ public sealed class MeetingArtifactFrontmatter
|
||||
|
||||
public List<string>? Attendees { get; set; }
|
||||
|
||||
public List<string>? Projects { get; set; }
|
||||
|
||||
public string Meeting { get; set; } = "";
|
||||
|
||||
public string Transcript { get; set; } = "";
|
||||
@@ -39,6 +41,7 @@ public static class MeetingArtifactFrontmatterRenderer
|
||||
AppendDateTime(builder, "start_time", frontmatter.StartTime);
|
||||
AppendDateTime(builder, "end_time", frontmatter.EndTime);
|
||||
AppendListIfNotNull(builder, "attendees", frontmatter.Attendees);
|
||||
AppendListIfNotNull(builder, "projects", frontmatter.Projects);
|
||||
AppendQuotedIfNotEmpty(builder, "meeting", frontmatter.Meeting);
|
||||
AppendQuotedIfNotEmpty(builder, "transcript", frontmatter.Transcript);
|
||||
AppendQuotedIfNotEmpty(builder, "assistant_context", frontmatter.AssistantContext);
|
||||
|
||||
@@ -107,6 +107,7 @@ public sealed class MeetingSummaryTools
|
||||
string.IsNullOrWhiteSpace(summaryTitle) ? "Meeting Summary" : summaryTitle,
|
||||
artifacts.SummaryPath);
|
||||
frontmatter.Attendees = await ResolveSummaryAttendeesAsync(meetingNote);
|
||||
frontmatter.Projects = ResolveSummaryProjects(meetingNote);
|
||||
await File.WriteAllTextAsync(
|
||||
artifacts.SummaryPath,
|
||||
MeetingArtifactFrontmatterRenderer.Render(frontmatter, markdown));
|
||||
@@ -591,6 +592,13 @@ public sealed class MeetingSummaryTools
|
||||
: meetingNote.Frontmatter.Attendees.ToList();
|
||||
}
|
||||
|
||||
private static List<string>? ResolveSummaryProjects(MeetingNote meetingNote)
|
||||
{
|
||||
return meetingNote.Frontmatter.Projects.Count == 0
|
||||
? null
|
||||
: meetingNote.Frontmatter.Projects.ToList();
|
||||
}
|
||||
|
||||
private async Task<List<string>?> ReadExistingSummaryAttendeesAsync()
|
||||
{
|
||||
if (!File.Exists(artifacts.SummaryPath))
|
||||
|
||||
@@ -61,7 +61,7 @@ After writing the meeting summary, the summary agent SHALL update existing proje
|
||||
|
||||
The assistant context note SHALL keep `title`, `start_time`, `end_time`, `meeting`, `transcript`, `summary`, `state`, and `agenda` in frontmatter. Meeting Assistant SHALL write `title` and `start_time` when the assistant context note is created, update `title` when later meeting metadata is discovered, and write `end_time` when transcript processing stops. When a Teams appointment is detected at recording start, the assistant context note SHALL also keep `scheduled_end` in frontmatter. The `state` value SHALL be one of `collecting metadata`, `transcribing`, `speaker recognition`, `summarizing`, `finished`, or `error`.
|
||||
|
||||
The summary note SHALL keep frontmatter links to meeting artifacts and SHALL copy `title`, `start_time`, `end_time`, and `attendees` from the meeting note when available. If the meeting note has no title, the summary agent SHALL be able to provide a title when writing the summary.
|
||||
The summary note SHALL keep frontmatter links to meeting artifacts and SHALL copy `title`, `start_time`, `end_time`, `attendees`, and `projects` from the meeting note when available. If the meeting note has no title, the summary agent SHALL be able to provide a title when writing the summary.
|
||||
|
||||
When the summary note already has an `attendees` frontmatter property, Meeting Assistant SHALL preserve the existing summary attendees instead of overwriting them from the meeting note.
|
||||
|
||||
@@ -88,6 +88,10 @@ The summary agent SHALL be able to read and write the assistant context body as
|
||||
- **WHEN** the summary agent rewrites the summary
|
||||
- **THEN** Meeting Assistant preserves the existing summary attendees
|
||||
|
||||
#### Scenario: Summary copies final meeting projects
|
||||
- **WHEN** the summary agent writes a summary note after meeting projects have changed
|
||||
- **THEN** the summary note frontmatter includes the final meeting note projects
|
||||
|
||||
#### Scenario: Summary waits for pending screenshot OCR
|
||||
- **GIVEN** screenshot OCR is still running for a meeting
|
||||
- **WHEN** transcript processing is ready to run the automatic summary
|
||||
|
||||
Reference in New Issue
Block a user