From d6959985b50bb1354e1f3ab0c9ff963e97a25c00 Mon Sep 17 00:00:00 2001 From: Jacob Smith Date: Wed, 18 Mar 2026 13:14:27 -0700 Subject: [PATCH 01/38] AB#32012 move AI files into concern folders --- .../AI/{ => Capture}/AIPromptCaptureStore.cs | 0 .../AI/{ => Capture}/IAIPromptCaptureStore.cs | 0 .../AI/{ => Extraction}/TextExtractionService.cs | 0 .../AI/{ => Operations}/ApplicationAnalysisService.cs | 0 .../AI/{ => Operations}/ApplicationScoresheetAnalysisService.cs | 0 .../AI/{ => Operations}/IApplicationAnalysisService.cs | 0 .../AI/{ => Operations}/IApplicationScoresheetAnalysisService.cs | 0 .../AI/{ => Prompts}/AIPromptTypes.cs | 0 .../AI/{ => Prompts}/PromptDataPayloadBuilder.cs | 0 .../AI/{ => Runtime}/AIOperationResult.cs | 0 .../AI/{ => Runtime}/AIProviderResponse.cs | 0 .../AI/{ => Runtime}/AIProviderResponseMetadata.cs | 0 .../AI/{ => Runtime}/AIResponseJson.cs | 0 .../AI/{ => Runtime}/AIResponseValidator.cs | 0 .../AI/{ => Runtime}/OpenAIService.cs | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Capture}/AIPromptCaptureStore.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Capture}/IAIPromptCaptureStore.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Extraction}/TextExtractionService.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Operations}/ApplicationAnalysisService.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Operations}/ApplicationScoresheetAnalysisService.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Operations}/IApplicationAnalysisService.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Operations}/IApplicationScoresheetAnalysisService.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Prompts}/AIPromptTypes.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Prompts}/PromptDataPayloadBuilder.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Runtime}/AIOperationResult.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Runtime}/AIProviderResponse.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Runtime}/AIProviderResponseMetadata.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Runtime}/AIResponseJson.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Runtime}/AIResponseValidator.cs (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/{ => Runtime}/OpenAIService.cs (100%) diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIPromptCaptureStore.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Capture/AIPromptCaptureStore.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIPromptCaptureStore.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Capture/AIPromptCaptureStore.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/IAIPromptCaptureStore.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Capture/IAIPromptCaptureStore.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/IAIPromptCaptureStore.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Capture/IAIPromptCaptureStore.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/TextExtractionService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Extraction/TextExtractionService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/TextExtractionService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Extraction/TextExtractionService.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/ApplicationAnalysisService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAnalysisService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/ApplicationAnalysisService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAnalysisService.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/ApplicationScoresheetAnalysisService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationScoresheetAnalysisService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/ApplicationScoresheetAnalysisService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationScoresheetAnalysisService.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/IApplicationAnalysisService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAnalysisService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/IApplicationAnalysisService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAnalysisService.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/IApplicationScoresheetAnalysisService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationScoresheetAnalysisService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/IApplicationScoresheetAnalysisService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationScoresheetAnalysisService.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIPromptTypes.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Prompts/AIPromptTypes.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIPromptTypes.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Prompts/AIPromptTypes.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/PromptDataPayloadBuilder.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Prompts/PromptDataPayloadBuilder.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/PromptDataPayloadBuilder.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Prompts/PromptDataPayloadBuilder.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIOperationResult.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIOperationResult.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIOperationResult.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIOperationResult.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIProviderResponse.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIProviderResponse.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIProviderResponse.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIProviderResponse.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIProviderResponseMetadata.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIProviderResponseMetadata.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIProviderResponseMetadata.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIProviderResponseMetadata.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIResponseJson.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIResponseJson.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIResponseJson.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIResponseJson.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIResponseValidator.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIResponseValidator.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/AIResponseValidator.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIResponseValidator.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/OpenAIService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/OpenAIService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/OpenAIService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/OpenAIService.cs From 1a48664d71fff425b9b54b2cfd8f51ec82591ae3 Mon Sep 17 00:00:00 2001 From: Jacob Smith Date: Wed, 18 Mar 2026 13:14:44 -0700 Subject: [PATCH 02/38] AB#32012 rename AI runtime and operation files --- ...licationAnalysisService.cs => ApplicationAIAnalysisService.cs} | 0 ...coresheetAnalysisService.cs => ApplicationAIScoringService.cs} | 0 ...icationAnalysisService.cs => IApplicationAIAnalysisService.cs} | 0 ...oresheetAnalysisService.cs => IApplicationAIScoringService.cs} | 0 .../{AIResponseValidator.cs => AIProviderPayloadValidator.cs} | 0 .../AI/Runtime/{AIProviderResponse.cs => AIProviderResult.cs} | 0 .../AI/Runtime/{OpenAIService.cs => OpenAIRuntimeService.cs} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/{ApplicationAnalysisService.cs => ApplicationAIAnalysisService.cs} (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/{ApplicationScoresheetAnalysisService.cs => ApplicationAIScoringService.cs} (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/{IApplicationAnalysisService.cs => IApplicationAIAnalysisService.cs} (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/{IApplicationScoresheetAnalysisService.cs => IApplicationAIScoringService.cs} (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/{AIResponseValidator.cs => AIProviderPayloadValidator.cs} (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/{AIProviderResponse.cs => AIProviderResult.cs} (100%) rename applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/{OpenAIService.cs => OpenAIRuntimeService.cs} (100%) diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAnalysisService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIAnalysisService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAnalysisService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIAnalysisService.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationScoresheetAnalysisService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIScoringService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationScoresheetAnalysisService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIScoringService.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAnalysisService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIAnalysisService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAnalysisService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIAnalysisService.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationScoresheetAnalysisService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIScoringService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationScoresheetAnalysisService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIScoringService.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIResponseValidator.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIProviderPayloadValidator.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIResponseValidator.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIProviderPayloadValidator.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIProviderResponse.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIProviderResult.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIProviderResponse.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/AIProviderResult.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/OpenAIService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/OpenAIRuntimeService.cs similarity index 100% rename from applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/OpenAIService.cs rename to applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Runtime/OpenAIRuntimeService.cs From 44891b4732dd343c60f2ea7afa03bf382c566a74 Mon Sep 17 00:00:00 2001 From: Jacob Smith Date: Wed, 18 Mar 2026 13:19:08 -0700 Subject: [PATCH 03/38] AB#32012 extract attachment AI orchestration and align runtime types --- .../ApplicationAIAnalysisService.cs | 4 +- .../Operations/ApplicationAIScoringService.cs | 4 +- .../Operations/AttachmentAISummaryService.cs | 106 ++++++++++++++++++ .../IApplicationAIAnalysisService.cs | 2 +- .../IApplicationAIScoringService.cs | 2 +- .../Operations/IAttachmentAISummaryService.cs | 12 ++ .../AI/Prompts/Versions/README.md | 2 +- .../AI/Runtime/AIOperationResult.cs | 18 +-- .../AI/Runtime/AIProviderPayloadValidator.cs | 2 +- .../AI/Runtime/AIProviderResult.cs | 4 +- .../AI/Runtime/OpenAIRuntimeService.cs | 33 +++--- .../Attachments/AttachmentAppService.cs | 91 +-------------- .../ApplicationAIAnalysisAppService.cs | 2 +- .../ApplicationAIScoringAppService.cs | 2 +- .../Handlers/GenerateAIContentHandler.cs | 73 +----------- 15 files changed, 165 insertions(+), 192 deletions(-) create mode 100644 applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/AttachmentAISummaryService.cs create mode 100644 applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IAttachmentAISummaryService.cs diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIAnalysisService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIAnalysisService.cs index 4b633cfd82..fc73aed9ae 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIAnalysisService.cs +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIAnalysisService.cs @@ -10,13 +10,13 @@ namespace Unity.GrantManager.AI { - public class ApplicationAnalysisService( + public class ApplicationAIAnalysisService( IApplicationRepository applicationRepository, IApplicationFormSubmissionRepository applicationFormSubmissionRepository, IApplicationFormVersionRepository applicationFormVersionRepository, IApplicationChefsFileAttachmentRepository applicationChefsFileAttachmentRepository, IAIService aiService, - ILogger logger) : IApplicationAnalysisService, ITransientDependency + ILogger logger) : IApplicationAIAnalysisService, ITransientDependency { private readonly JsonSerializerOptions _jsonOptionsIndented = new() { diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIScoringService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIScoringService.cs index 82b7c12ae4..01c8c5516a 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIScoringService.cs +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/ApplicationAIScoringService.cs @@ -10,7 +10,7 @@ namespace Unity.GrantManager.AI { - public class ApplicationScoresheetAnalysisService( + public class ApplicationAIScoringService( IApplicationRepository applicationRepository, IApplicationFormRepository applicationFormRepository, IApplicationFormSubmissionRepository applicationFormSubmissionRepository, @@ -18,7 +18,7 @@ public class ApplicationScoresheetAnalysisService( IApplicationChefsFileAttachmentRepository applicationChefsFileAttachmentRepository, IScoresheetRepository scoresheetRepository, IAIService aiService, - ILogger logger) : IApplicationScoresheetAnalysisService, ITransientDependency + ILogger logger) : IApplicationAIScoringService, ITransientDependency { private readonly JsonSerializerOptions _jsonOptions = new() { diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/AttachmentAISummaryService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/AttachmentAISummaryService.cs new file mode 100644 index 0000000000..2007dee084 --- /dev/null +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/AttachmentAISummaryService.cs @@ -0,0 +1,106 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Unity.GrantManager.Applications; +using Unity.GrantManager.Intakes; +using Volo.Abp.DependencyInjection; + +namespace Unity.GrantManager.AI; + +public class AttachmentAISummaryService( + IApplicationChefsFileAttachmentRepository applicationChefsFileAttachmentRepository, + ISubmissionAppService submissionAppService, + IAIService aiService, + ILogger logger) : IAttachmentAISummaryService, ITransientDependency +{ + private const string DefaultContentType = "application/octet-stream"; + private const string SummaryGenerationFailedMessage = "AI summary generation failed."; + + public async Task GenerateAndSaveAsync(Guid attachmentId, string? promptVersion = null, bool capturePromptIo = false) + { + var attachment = await applicationChefsFileAttachmentRepository.GetAsync(attachmentId); + var fileName = string.IsNullOrWhiteSpace(attachment.FileName) ? "unknown" : attachment.FileName; + var (fileContent, contentType) = await GetAttachmentContentForSummaryAsync(attachment, fileName); + + var summaryResponse = await aiService.GenerateAttachmentSummaryAsync(new AttachmentSummaryRequest + { + FileName = fileName, + FileContent = fileContent, + ContentType = contentType, + PromptVersion = promptVersion, + CapturePromptIo = capturePromptIo, + CaptureContextId = attachment.ApplicationId.ToString() + }); + + attachment.AISummary = summaryResponse.Summary; + await applicationChefsFileAttachmentRepository.UpdateAsync(attachment); + + return summaryResponse.Summary; + } + + public async Task> GenerateAndSaveAsync(IEnumerable attachmentIds, string? promptVersion = null, bool capturePromptIo = false) + { + var summaries = new List(); + + foreach (var attachmentId in attachmentIds) + { + try + { + summaries.Add(await GenerateAndSaveAsync(attachmentId, promptVersion, capturePromptIo)); + } + catch (Exception ex) + { + logger.LogError(ex, "Error generating AI summary for attachment {AttachmentId}", attachmentId); + summaries.Add(SummaryGenerationFailedMessage); + } + } + + return summaries; + } + + public async Task> GenerateMissingForApplicationAsync(Guid applicationId, string? promptVersion = null, bool capturePromptIo = false) + { + var attachmentIds = (await applicationChefsFileAttachmentRepository.GetListAsync(a => + a.ApplicationId == applicationId && string.IsNullOrWhiteSpace(a.AISummary))) + .Select(a => a.Id) + .ToList(); + + return await GenerateAndSaveAsync(attachmentIds, promptVersion, capturePromptIo); + } + + private async Task<(byte[] Content, string ContentType)> GetAttachmentContentForSummaryAsync(ApplicationChefsFileAttachment attachment, string fileName) + { + if (!Guid.TryParse(attachment.ChefsSubmissionId, out var submissionId) || + !Guid.TryParse(attachment.ChefsFileId, out var fileId)) + { + logger.LogWarning( + "Attachment {AttachmentId} has invalid CHEFS IDs. Falling back to metadata-only summary generation.", + attachment.Id); + return (Array.Empty(), DefaultContentType); + } + + try + { + var fileDto = await submissionAppService.GetChefsFileAttachment(submissionId, fileId, fileName); + if (fileDto?.Content == null) + { + logger.LogWarning( + "Attachment {AttachmentId} has no retrievable content. Falling back to metadata-only summary generation.", + attachment.Id); + return (Array.Empty(), DefaultContentType); + } + + return (fileDto.Content, string.IsNullOrWhiteSpace(fileDto.ContentType) ? DefaultContentType : fileDto.ContentType); + } + catch (Exception ex) + { + logger.LogWarning( + ex, + "Failed retrieving CHEFS content for attachment {AttachmentId}. Falling back to metadata-only summary generation.", + attachment.Id); + return (Array.Empty(), DefaultContentType); + } + } +} diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIAnalysisService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIAnalysisService.cs index 172a3b9c5a..382cee8120 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIAnalysisService.cs +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIAnalysisService.cs @@ -3,7 +3,7 @@ namespace Unity.GrantManager.AI { - public interface IApplicationAnalysisService + public interface IApplicationAIAnalysisService { Task RegenerateAndSaveAsync(Guid applicationId, string? promptVersion = null, bool capturePromptIo = false); } diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIScoringService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIScoringService.cs index 1cc4ef1ffa..01b1241069 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIScoringService.cs +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IApplicationAIScoringService.cs @@ -3,7 +3,7 @@ namespace Unity.GrantManager.AI { - public interface IApplicationScoresheetAnalysisService + public interface IApplicationAIScoringService { Task RegenerateAndSaveAsync(Guid applicationId, string? promptVersion = null, bool capturePromptIo = false); } diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IAttachmentAISummaryService.cs b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IAttachmentAISummaryService.cs new file mode 100644 index 0000000000..021f9128c6 --- /dev/null +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Operations/IAttachmentAISummaryService.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Unity.GrantManager.AI; + +public interface IAttachmentAISummaryService +{ + Task GenerateAndSaveAsync(Guid attachmentId, string? promptVersion = null, bool capturePromptIo = false); + Task> GenerateAndSaveAsync(IEnumerable attachmentIds, string? promptVersion = null, bool capturePromptIo = false); + Task> GenerateMissingForApplicationAsync(Guid applicationId, string? promptVersion = null, bool capturePromptIo = false); +} diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Prompts/Versions/README.md b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Prompts/Versions/README.md index 0a2ae41b7b..fa8d0bf790 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Prompts/Versions/README.md +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Application/AI/Prompts/Versions/README.md @@ -1,7 +1,7 @@ # Runtime Prompt Templates These files are the source of truth for runtime prompts. -`OpenAIService` resolves templates from: +`OpenAIRuntimeService` resolves templates from: - `AI/Prompts/Versions//