Public Access
feat: attach calendar metadata to active meetings
PR and Push Build/Test / build-and-test (push) Successful in 15m2s
PR and Push Build/Test / build-and-test (push) Successful in 15m2s
This commit is contained in:
@@ -155,6 +155,44 @@ public sealed class MeetingRecordingCoordinator
|
||||
return await StartAsync(null, metadata, suppressMetadataLookup: true, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<RecordingStatus> AttachMetadataToCurrentMeetingAsync(
|
||||
MeetingMetadata metadata,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await gate.WaitAsync(cancellationToken);
|
||||
try
|
||||
{
|
||||
var run = currentRun;
|
||||
if (run is null || run.IsCaptureStopping)
|
||||
{
|
||||
return CurrentStatus;
|
||||
}
|
||||
|
||||
var meetingNote = await ApplyAndPersistMeetingMetadataAsync(
|
||||
run.Artifacts,
|
||||
await meetingNoteStore.ReadAsync(run.MeetingNotePath, cancellationToken),
|
||||
metadata,
|
||||
run.Options,
|
||||
cancellationToken);
|
||||
currentMeetingNote = meetingNote;
|
||||
await transcriptStore.UpdateMetadataAsync(
|
||||
run.Session,
|
||||
run.Artifacts,
|
||||
meetingNote,
|
||||
cancellationToken);
|
||||
run.MarkPromptMetadataAttached();
|
||||
|
||||
logger.LogInformation(
|
||||
"Attached prompted calendar metadata to active meeting {MeetingNotePath}",
|
||||
run.MeetingNotePath);
|
||||
return CurrentStatus;
|
||||
}
|
||||
finally
|
||||
{
|
||||
gate.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RecordingStatus> StartAsync(
|
||||
string? launchProfileName,
|
||||
CancellationToken cancellationToken)
|
||||
@@ -213,22 +251,12 @@ public sealed class MeetingRecordingCoordinator
|
||||
currentMeetingNote = await meetingNoteStore.ReadAsync(currentMeetingNote.Path, cancellationToken);
|
||||
if (suppliedMetadata is not null)
|
||||
{
|
||||
await ApplyMeetingMetadataAsync(
|
||||
currentMeetingNote = await ApplyAndPersistMeetingMetadataAsync(
|
||||
currentArtifacts,
|
||||
currentMeetingNote,
|
||||
suppliedMetadata,
|
||||
runOptions,
|
||||
cancellationToken);
|
||||
currentMeetingNote = await meetingNoteStore.SaveAsync(
|
||||
currentMeetingNote,
|
||||
runOptions,
|
||||
cancellationToken);
|
||||
await meetingArtifactStore.UpdateAssistantContextMetadataAsync(
|
||||
currentArtifacts,
|
||||
currentMeetingNote,
|
||||
suppliedMetadata.Agenda,
|
||||
suppliedMetadata.ScheduledEnd,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
await meetingArtifactStore.UpdateAssistantContextMeetingAsync(
|
||||
@@ -1021,7 +1049,7 @@ public sealed class MeetingRecordingCoordinator
|
||||
return;
|
||||
}
|
||||
|
||||
if (run.IsAborted)
|
||||
if (run.IsAborted || run.HasAttachedPromptMetadata)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1029,25 +1057,21 @@ public sealed class MeetingRecordingCoordinator
|
||||
await gate.WaitAsync(CancellationToken.None);
|
||||
try
|
||||
{
|
||||
if (run.IsAborted)
|
||||
if (run.IsAborted || run.HasAttachedPromptMetadata)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var meetingNote = await meetingNoteStore.ReadAsync(run.MeetingNotePath, CancellationToken.None);
|
||||
await ApplyMeetingMetadataAsync(run.Artifacts, meetingNote, metadata, run.Options, CancellationToken.None);
|
||||
meetingNote = await meetingNoteStore.SaveAsync(meetingNote, run.Options, CancellationToken.None);
|
||||
var meetingNote = await ApplyAndPersistMeetingMetadataAsync(
|
||||
run.Artifacts,
|
||||
await meetingNoteStore.ReadAsync(run.MeetingNotePath, CancellationToken.None),
|
||||
metadata,
|
||||
run.Options,
|
||||
CancellationToken.None);
|
||||
if (currentMeetingNote?.Path == meetingNote.Path)
|
||||
{
|
||||
currentMeetingNote = meetingNote;
|
||||
}
|
||||
|
||||
await meetingArtifactStore.UpdateAssistantContextMetadataAsync(
|
||||
run.Artifacts,
|
||||
meetingNote,
|
||||
metadata.Agenda,
|
||||
metadata.ScheduledEnd,
|
||||
CancellationToken.None);
|
||||
logger.LogInformation(
|
||||
"Applied Outlook meeting metadata to {MeetingNotePath}",
|
||||
run.MeetingNotePath);
|
||||
@@ -1119,6 +1143,32 @@ public sealed class MeetingRecordingCoordinator
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<MeetingNote> ApplyAndPersistMeetingMetadataAsync(
|
||||
MeetingSessionArtifacts artifacts,
|
||||
MeetingNote meetingNote,
|
||||
MeetingMetadata metadata,
|
||||
MeetingAssistantOptions options,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await ApplyMeetingMetadataAsync(
|
||||
artifacts,
|
||||
meetingNote,
|
||||
metadata,
|
||||
options,
|
||||
cancellationToken);
|
||||
var savedMeetingNote = await meetingNoteStore.SaveAsync(
|
||||
meetingNote,
|
||||
options,
|
||||
cancellationToken);
|
||||
await meetingArtifactStore.UpdateAssistantContextMetadataAsync(
|
||||
artifacts,
|
||||
savedMeetingNote,
|
||||
metadata.Agenda,
|
||||
metadata.ScheduledEnd,
|
||||
cancellationToken);
|
||||
return savedMeetingNote;
|
||||
}
|
||||
|
||||
private async Task<List<string>> TransformAttendeesAsync(
|
||||
MeetingSessionArtifacts artifacts,
|
||||
IReadOnlyList<string> attendees,
|
||||
@@ -1908,6 +1958,8 @@ public sealed class MeetingRecordingCoordinator
|
||||
|
||||
public bool HasSwitchedProfile { get; private set; }
|
||||
|
||||
public bool HasAttachedPromptMetadata { get; private set; }
|
||||
|
||||
public AssistantContextState ContextState { get; private set; } = AssistantContextState.CollectingMetadata;
|
||||
|
||||
public DateTimeOffset? InferredEndTime
|
||||
@@ -1926,6 +1978,11 @@ public sealed class MeetingRecordingCoordinator
|
||||
CaptureCancellationSource.Cancel();
|
||||
}
|
||||
|
||||
public void MarkPromptMetadataAttached()
|
||||
{
|
||||
HasAttachedPromptMetadata = true;
|
||||
}
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
IsAborted = true;
|
||||
|
||||
Reference in New Issue
Block a user