using MeetingAssistant.MeetingNotes; namespace MeetingAssistant.Summary; public interface IMeetingSummaryRetryRunner { Task TriggerAsync( string summaryPath, MeetingAssistantOptions options, CancellationToken cancellationToken); } public sealed record MeetingSummaryRetryTriggerResult( string SummaryPath, string AssistantContextPath); public sealed class MeetingSummaryRetryRunner : IMeetingSummaryRetryRunner { private readonly IMeetingSummaryArtifactResolver artifactResolver; private readonly IMeetingSummaryPipeline summaryPipeline; private readonly IMeetingArtifactStore artifactStore; private readonly ILogger logger; public MeetingSummaryRetryRunner( IMeetingSummaryArtifactResolver artifactResolver, IMeetingSummaryPipeline summaryPipeline, IMeetingArtifactStore artifactStore, ILogger logger) { this.artifactResolver = artifactResolver; this.summaryPipeline = summaryPipeline; this.artifactStore = artifactStore; this.logger = logger; } public async Task TriggerAsync( string summaryPath, MeetingAssistantOptions options, CancellationToken cancellationToken) { var artifacts = await artifactResolver.ResolveBySummaryPathAsync( summaryPath, options, cancellationToken); if (artifacts is null) { return null; } _ = Task.Run(() => RunRetryAsync(artifacts, options), CancellationToken.None); return new MeetingSummaryRetryTriggerResult( artifacts.SummaryPath, artifacts.AssistantContextPath); } private async Task RunRetryAsync( MeetingSessionArtifacts artifacts, MeetingAssistantOptions options) { try { await artifactStore.UpdateAssistantContextStateAsync( artifacts, AssistantContextState.Summarizing, CancellationToken.None); var result = await summaryPipeline.RunAsync( artifacts, options, CancellationToken.None); await artifactStore.UpdateAssistantContextStateAsync( artifacts, result.Succeeded ? AssistantContextState.Finished : AssistantContextState.Error, CancellationToken.None); } catch (Exception exception) { logger.LogError( exception, "Summary retry failed unexpectedly for {SummaryPath}", artifacts.SummaryPath); try { await artifactStore.UpdateAssistantContextStateAsync( artifacts, AssistantContextState.Error, CancellationToken.None); } catch (Exception stateException) { logger.LogWarning( stateException, "Could not mark assistant context error after summary retry failed for {SummaryPath}", artifacts.SummaryPath); } } } }